Franck Alary
Web developer at Rodez, France
Présenté par Franck ALARY
import React from 'react'
import ReactDOM from 'react-dom';
const HelloName = props => <div className="hello">Hello {props.name} !</div>
ReactDOM.render(
<HelloName name="Franck" />,
document.getElementById('app')
);
Voici un functional component.
Plusieurs fonctions pour faciliter les interactions utilisateur et le rafraichissement des données sur votre page.
import React, { useState } from 'react'
import ReactDOM from 'react-dom';
const Increment = () => {
const [counter, setCounter] = useState(0)
return (
<div className="counter" onClick={() => setCounter(counter + 1)}>
{counter}
</div>
)
}
ReactDOM.render(
<Increment />,
document.getElementById('app')
);
Voici un Hook
Vous devez avoir préalablement installé Nodejs.
npx create-react-app mon-app
cd mon-app
npm start
Et le tour est joué !
export default props => (
<div>
<h1>{props.title}</h1>
<p>{props.message}</p>
</div>
)
export default props => (
<>
<h1>{props.title}</h1>
<p>{props.message}</p>
</>
)
export default props => (
<React.Fragment>
<h1>{props.title}</h1>
<p>{props.message}</p>
</React.Fragment>
)
React.Fragment
export default props => props.text === undefined ? null : <p>{props.text}</p>
export default props => props.text !== undefined && <p>{props.text}</p>
Récupérer les enfants du composant
export default props => (
<div className="container">
{props.children}
</div>
)
export default props => {
const [title, text] = ({
1:['Mon titre 1', 'Mon texte 1'],
2:['Mon titre 2', 'Mon texte 2'],
3:['Mon titre 3', 'Mon texte 3'],
})[props.idContent]
return props.children(title, text)
}
export default props => (
<GetContent idContent={3}>{
(title, text) => (
<>
<h1>{title}</h1>
<p>{text}</p>
</>
)
}</GetContent>
)
GetContent.js
DisplayContent.js
export default props => (
<Container>
<p>Mon texte</p>
</Container>
)
import React from 'react'
import './MyStyle.css' // CSS Global
import styles1 from './MyStyle.module.css' // CSS pour le composant
import styles2 from './MyStyle.module.scss' // Sass pour le composant
export default props => (
<div className={myStyles1.container}>
<h1 className={[styles1.title, styles2.title].join(' ')}>Titre</h1>
{props.children}
</div>
)
CSS module implémenté et configuré par défaut avec npx create-react-app.
npm install node-sass
Pour ajouter Sass au projet
Liste non exhaustive
(Les très utiles)
import React, { useState } from 'react'
import ReactDOM from 'react-dom';
const Increment = () => {
const [counter, setCounter] = useState(0)
return (
<div className="counter">
<p>{counter}</p>
<ul>
<li onClick={() => setCounter(counter - 1)}>-</li>
<li onClick={() => setCounter(counter + 1)}>+</li>
</ul>
</div>
)
}
ReactDOM.render(
<Increment />,
document.getElementById('app')
)
import React, { useState, useEffect } from 'react'
import ReactDOM from 'react-dom';
const Increment = () => {
const [counter, setCounter] = useState(0)
useEffect(() => {
alert('Le composant vient d\'être initialisé dans le navigateur !')
}, [])
useEffect(() => {
alert('Le composant vient d\'être actualisé dans le navigateur !')
})
useEffect(() => {
alert('Le state counter vient d\'être mis à jour dans le navigateur !')
},[counter])
return (
<div className="counter" onClick={() => setCounter(counter + 1)}>
{counter}
</div>
)
}
ReactDOM.render(
<Increment />,
document.getElementById('app')
)
import React, { useState, useEffect } from 'react'
import ReactDOM from 'react-dom'
const CountDown = props => {
const [counter, setCounter] = useState(10)
useEffect(
() => {counter > 0 && setTimeout(() => setCounter(counter - 1), 1000)},
[counter]
)
return <div>{counter}</div>
}
ReactDOM.render(
<CountDown/>,
document.getElementById('app')
)
import React, { useState, useEffect } from 'react'
import ReactDOM from 'react-dom';
const MyMessage = props => {
useEffect(
() => alert('Message vient d\'être mise à jour dans le navigateur !'),
[props.message]
)
return <div>{props.message}</div>
}
ReactDOM.render(
<MyMessage message="Hello World !" />,
document.getElementById('app')
)
import React, { useState, useEffect } from 'react'
import ReactDOM from 'react-dom';
const FadeIn = props => {
const [classComponent, setClassComponent] = useState('hidden-block')
useEffect(() => setClassComponent('displayed-block'), [])
return <div className={classComponent}>{props.message}</div>
}
ReactDOM.render(
<FadeIn message="Hello World !" />,
document.getElementById('app')
)
.hidden-block, .displayed-block {transition: opacity 0.3s}
.hidden-block {opacity: 0}
.displayed-block {opacity: 1}
CSS
JavaScript
import React, { useState, useEffect } from 'react'
import ReactDOM from 'react-dom'
const
MouseTracking = props => {
const [mousePosition, setMousePosition] = useState({x: 0, y: 0})
useEffect(() => {
const trackMousePosition = (e) => {
const event = e || window.event
setMousePosition({x: event.pageX, y: event.pageY})
}
document.addEventListener('mousemove', trackMousePosition)
return () => document.removeEventListener('mousemove', trackMousePosition)
}, [])
return (
<div onClick={() => props.closeMouseTracking(true)}>
<h1>Mouse position</h1>
<ul>
<li>X : {mousePosition.x}</li>
<li>Y : {mousePosition.y}</li>
</ul>
</div>
)
},
Container = () => {
const [isClosed, setClose] = useState(false)
return !isClosed && <MouseTracking closeMouseTracking={setClose}/>
}
ReactDOM.render(<Container/>, document.getElementById('app'))
import { createContext } from 'react'
const
themes = {
light: {
color: '#000000',
background: '#eeeeee'
},
dark: {
color: '#ffffff',
background: '#222222'
}
},
ContextTheme = createContext(themes.light)
export { themes, ContextTheme }
ContextTheme.js
import React from 'react'
import { ContextTheme, themes } from './ContextTheme'
import ThemedButton from './ThemedButton'
export default () => {
return (
<>
<ThemedButton/>
<ContextTheme.Provider value={themes.dark}>
<ThemedButton/>
</ContextTheme.Provider>
</>
)
}
App.js
import React, { useContext } from 'react'
import { ContextTheme } from './ContextTheme'
export default () => {
const theme = useContext(ContextTheme)
return <button style={theme}>Mon bouton !</button>
}
ThemedButton.js
import React, { useReducer } from 'react'
import ReactDOM from 'react-dom'
const
reducer = (state, action) => {
switch (action.type) {
case 'increment':
return {count: state.count + 1}
case 'decrement':
return {count: state.count - 1}
default:
throw new Error()
}
},
Counter = () => {
const [state, dispatch] = useReducer(reducer, {count: 0})
return (
<>
<div>Total : {state.count}</div>
<ul>
<li onClick={() => dispatch({type: 'decrement'})}>-</li>
<li onClick={() => dispatch({type: 'increment'})}>+</li>
</ul>
</>
)
}
ReactDOM.render(
<Counter/>,
document.getElementById('app')
)
import React, { useMemo } from 'react'
import ReactDOM from 'react-dom'
const Product = props => {
const priceWeightKg = useMemo(
() => Math.round(props.price * 1000 / props.weight) / 100,
[props.price, props.weight]
)
return (
<ul>
<li>Name : {props.name}</li>
<li>Weight (gr.) : {props.weight}</li>
<li>Price : {props.price}</li>
<li>Price/Kg : {priceWeightKg}</li>
</ul>
)
}
ReactDOM.render(
<Product name="Sandwish" price={4.5} weight={300}/>,
document.getElementById('app')
)
import React, { useState, useRef } from 'react'
import ReactDOM from 'react-dom'
const FormCustom = () => {
const
[value, setValue] = useState(''),
input = useRef(null)
return (
<div>
<p>{value}</p>
<input type="text" ref={input}/>
<button onClick={() => setValue(input.current.value)}>GET VALUE !</button>
<button onClick={() => input.current.focus()}>FOCUS !</button>
</div>
)
}
ReactDOM.render(
<FormCustom/>,
document.getElementById('app')
)
Server side rendering avec Nodejs et React
afin de réaliser des sites Internet isomorphiques.
npx create-next-app
Pour gérer un état global de l'application avec des hooks.
npm install reactn
import React, { useGlobal } from 'reactn';
export default () => {
const [user, setUser] = useGlobal('user')
return (
<ul>
<li>Nom : {user.name}</li>
<li>Identifiant : {user.mail}</li>
<li>Pseudo : {user.nickname}</li>
</ul>
)
}
import React, { useGlobal } from 'reactn';
export default () => {
const [user, setUser] = useGlobal('user')
return <input type="text"
defaultValue={user.name}
onChange={(e) => setUser({...user, name:e.target.value})}/>
}
Pour gérer les cookies avec des hooks.
import React from 'react'
import { useCookies } from 'react-cookie'
export default () => {
const [cookies, setCookie, removeCookie] = useCookies(['name'])
return <input type="text"
defaultValue={cookies.name}
onChange={(e) => setCookie('name', e.target.value, {path: '/'})}/>
}
npm install react-cookie
Pour utiliser l'API de géolocalisation du navigateur.
npm install react-geolocated
import React from 'react'
import { geolocated, geoPropTypes } from 'react-geolocated'
import ErrorMessage from './ErrorMessage'
const GeolocateStop = props => {
if (!props.isGeolocationAvailable) {
return <ErrorMessage message="Géolocalisation non supportée..."/>
}
if (!props.isGeolocationEnabled) {
return <ErrorMessage message="Géolocalisation non activée..."/>
}
if (!!props.positionError) {
return <ErrorMessage message="Erreur de géolocalisation..."/>
}
if (!props.coords) {
return <ErrorMessage message="Recherche..."/>
}
return <h1>Votre position : Lat {props.coords.latitude}, Lng {props.coords.longitude}</h1>
}
GeolocateStop.propTypes = {...GeolocateStop.propTypes, ...geoPropTypes}
export default geolocated()(GeolocateStop)
La communauté autour de React est très grande et active !!
Franck ALARY
github.com/DantSu
www.developpeur-web.dantsu.com
Slides
slides.com/dantsu/functional-components-hooks-
la-nouvelle-methode-react
By Franck Alary