Slide 1

Slide 1 text

Zacznij używaćHooków() w Reakcie

Slide 2

Slide 2 text

Hooki? A co to?

Slide 3

Slide 3 text

Hooki? A co to? — propozycja nowego API reacta — nic magicznego, wbrew pierwszemu wrażeniu — funkcje, które dają większe moźliwości komponentom funkcyjnym — dodają m.in. stan, efekty uboczne oraz referencje

Slide 4

Slide 4 text

Hooki? A po co to komu?

Slide 5

Slide 5 text

Hooki? A po co to komu? — Umożliwiają tworzenie prawie wszystkiego za pomocą funkcjonalnych komponentów — Zwiększają reużywalność kodu (zwłaszcza w obrębie efektów ubocznych) — eliminują część zastosowań HOC i renderProps

Slide 6

Slide 6 text

ReactJS krótkie przypomnienie

Slide 7

Slide 7 text

Funkcyjny komponent function Product(props) { return (
props.onClick(props)}>

{props.name}

For only ${props.price}
); }

Slide 8

Slide 8 text

Funkcyjny komponent function Products({ products, onProductClick }) { return (
{products ? (

Products:

{products.map(product => ( ))}
) : (

Loading products...

)}
); }

Slide 9

Slide 9 text

Komponent klasowy class ProductsPage extends React.Component { state = { products: [] } componentDidMount() { fetchProducts().then(results => this.setState({ products: results })) } render() { return ( ); } }

Slide 10

Slide 10 text

Komponent funkcyjny z hookami function ProductsPage() { const [products, setProducts] = useState([]); setEffect(() => { fetchProducts().then(results => setProducts(results)); }, []) return ( ); }

Slide 11

Slide 11 text

Najważniejsze wbudowane hooki — useState() — useEffect() — useRef() — useContext()

Slide 12

Slide 12 text

Pozostałe wbudowane hooki — useLayoutEffect() — useMutationEffect() — useImperativeMethods() — useMemo() — useCallback() — useReducer()

Slide 13

Slide 13 text

useState()

Slide 14

Slide 14 text

useState() Pozwala na używanie stanu w komponentach funkcyjnych const [currentState, stateSetterFunction] = useState(initialState);

Slide 15

Slide 15 text

useState() Na przykład function SillyEmailComponent() { const [email, setEmail] = useState("[email protected]"); return (

{email}

setEmail("[email protected]")} />
) }

Slide 16

Slide 16 text

useState() Odpowiednik w klasowym komponencie class SillyEmailComponent extends ReactComponent { state = { email: "[email protected]" }; render() { return (

{this.state.email}

this.setState({ email: "[email protected]" })} />
) } }

Slide 17

Slide 17 text

setState() Jeden stan na wiele danych class SillyEmailComponent extends ReactComponent { state = { email: "[email protected]", firstName: "Bob" }; render() { return (

"{this.state.firstName}" <{this.state.email}>

this.setState({ email: "[email protected]", firstName: "Alice" })} />
) } }

Slide 18

Slide 18 text

setState() działa wybiórczo state = { email: "[email protected]", firstName: "Bob" }; // This will update only email and leave firstName intact this.setState({ email: "Alice" });

Slide 19

Slide 19 text

useState() Nie uaktualnia stanu wybiórczo const [emailAndName, setEmailAndName] = useState({ email: "[email protected]", firstName: "Bob" }); // This will replace the whole state!!! setEmailAndName({ email: "Alice" }) // This will work as set state setEmailAndName(prevState => {...prevState, email: "Alice" })

Slide 20

Slide 20 text

useState() Pozwala mieć wiele niezależnych zniennych stanowych function SillyEmailComponent() { const [email, setEmail] = useState("[email protected]"); const [firstName, setFirstName] = useState("Bob"); return (

"{firstName}" <{email}>

{ setEmail("[email protected]") setFirstName("Alice") }} />
) }

Slide 21

Slide 21 text

useState() Se!er pozwala na zmianę za pomocą funkcji bardzo ważne jeśli nowy stan zależy od poprzedniego function Counter() { const [count, setCount] = useState(0); return (
Count: {count} setCount(0)}>Reset setCount(prevCount => prevCount + 1)}>+ setCount(prevCount => prevCount - 1)}>-
); }

Slide 22

Slide 22 text

useState() Odpowiednik w klasowym komponencie class Counter extends ReactComponent { state = { count: 0 }; render() { return (
Count: {count} setState({ count: 0)}>Reset setState(state => ({count: state.count + 1})}>+ setState(state => ({count: state.count - 1})}>-
) } }

Slide 23

Slide 23 text

useState() Pozwala na inicjalizacje za pomocą funkcji Przydatne jeśli to kosztowna operacja const [count, setCount] = useState(() => calculateFibonacciNumber(100)); Zamiast const [count, setCount] = useState(calculateFibonacciNumber(100));

Slide 24

Slide 24 text

useEffect()

Slide 25

Slide 25 text

useEffect() przyjmuje funkcję, która zajmie się efektami oraz (opcjonalną) tablicę zależności useEffect( functionThatHandlesEffect, arrayWithDependencies );

Slide 26

Slide 26 text

useEffect() domyślnie odpala funkcję po każdym renderze useEffect(() => { // will run after every render() window.document.title = "New title"; });

Slide 27

Slide 27 text

useEffect() odpowiednik w klasowym komponencie componentDidMount() { // will run after first render() window.document.title = "New title" } componentDidUpdate() { // will run after subsequent render() window.document.title = "New title" }

Slide 28

Slide 28 text

useEffect() pozwala posprzątać po sobie za pomocą funkcji zwróconej z funkcji efektu useEffect(() => { // will run after every render() const subscriptionId = subscribeToChannel(props.channelId); return () => { // will clean up before executing next effect // or before the component is removed from UI removeSubscription(subscriptionId); }; });

Slide 29

Slide 29 text

useEffect() może uruchamiać się warunkowo np. kiedy jakaś zależność się zmieni useEffect( () => { // will run only if channelId changes const subscriptionId = subscribeToChannel(props.channelId); return () => { // will clean up before executing next effect // or before the component is removed from UI removeSubscription(subscriptionId); }; }, [props.channelId] );

Slide 30

Slide 30 text

useEffect() uruchomi się tylko raz jeśli przekażemy pustą tablicę oznacza to brak zależności i brak potrzeby odświeźania useEffect( () => { // will run only after first render() const interval = setInterval(logSomethingEverySecond, 1000); return () => { // will clean up once // before the component is removed from UI clearInterval(interval); }; }, [] );

Slide 31

Slide 31 text

useEffect() odpowiednik w komponencie klasowym componentDidMount() { const this.interval = setInterval(logSomethingEverySecond, 1000); } componentWillUnmount() { clearInterval(this.interval); };

Slide 32

Slide 32 text

useRef()

Slide 33

Slide 33 text

useRef() Odpowiednik createRef w komponencie klasowym function CustomInput extends React.Component { constructor(props) { super(props) this.inputRef = React.createRef(); } setfocusOnInput = () => { this.inputRef.current.focus() } return (
Focus
) }

Slide 34

Slide 34 text

useRef() Pozwala na stworzenie obiektu referencji Przydatne gdy potrzebujemy dostać się do elementu DOM function CustomInput() { const inputRef = useRef(); function setfocusOnInput() { inputRef.current.focus() } return (
Focus
) }

Slide 35

Slide 35 text

useRef() Pozwala na tworzenie "zmiennych instancji" function CancellableTimeout(callback) { const timeoutRef = useRef(); useEffect(() => { timeoutRef.current = setTimeout(callback, 15000); return () => { clearTimeout(timeoutRef.current); } }) return (
clearTimeout(timeoutRef.current)}>Cancel timeout
) }

Slide 36

Slide 36 text

useContext()

Slide 37

Slide 37 text

useContext() Pozwala m.in. na wygodniejsze używanie kontekstu zwłaszcza dla wielu kontekstów

Slide 38

Slide 38 text

useContext() Zamiast function Message(props) { return ( {theme => ( { currentUser =>
{props.message}
} )} ) }

Slide 39

Slide 39 text

useContext() Mamy to function Message(props) { const theme = useContext(ThemeContext); const currentUser = useContext(UserContext); return (
You are logged in as {currentUser.name}
) }

Slide 40

Slide 40 text

Reguły używania hooków — Nie mogą być wywoływane wewnątrz instrukcji warunkowych, pętli, zagnieżdżonych funkcji itp. — kolejność wywoływania hooków musi być zachowana — Powinny się nazywać useXXX — Mogą byc wywoływane wewnątrz innych hooków

Slide 41

Slide 41 text

Demo Własne hooki

Slide 42

Slide 42 text

Chcesz więcej? kursreacta.pl/hooki @mehowte