Slide 1

Slide 1 text

React Hooks

Slide 2

Slide 2 text

React Hooks • released in React 16.8 • a new way to “hook into” React features • but first, let’s recap the API we have now

Slide 3

Slide 3 text

Class components

Slide 4

Slide 4 text

function MyComponent() { return }

Slide 5

Slide 5 text

class MyComponent extends React.Component { state = { email: '' } render() { return ( { this.setState({ email: event.target.value, }) }} "/> ); } }

Slide 6

Slide 6 text

function MyComponent({ value, onChange }) { return ( ) }

Slide 7

Slide 7 text

Pros • custom methods • reusing logic • naming logic

Slide 8

Slide 8 text

Cons • switching back and forth between functions and classes • a lot of typing • noisy Git diffs • class components are weird • we don’t instantiate them • we don’t extend them

Slide 9

Slide 9 text

Lifecycle methods

Slide 10

Slide 10 text

class MyComponent extends React.Component { constructor(props) static getDerivedStateFromProps(props, state) render() componentDidMount() shouldComponentUpdate(nextProps, nextState) getSnapshotBeforeUpdate(prevProps, prevState) componentDidUpdate(prevProps, prevState, snapshot) componentWillUnmount() }

Slide 11

Slide 11 text

Pros • transparency • descriptive method names • API is well documented • fine-grained control • easily target exact moment in the lifecycle

Slide 12

Slide 12 text

Cons • no way to escape the complexity • memorizing common pitfalls like endless loops • spreading a single feature across multiple methods

Slide 13

Slide 13 text

Higher-order components (HOCs)

Slide 14

Slide 14 text

import email from './hocs/email' function MyComponent({ email, handleEmailChange }) { return ( ) } export default email(MyComponent)

Slide 15

Slide 15 text

Pros • reusing complex behavior • we can keep using function components

Slide 16

Slide 16 text

Cons • readability • all props are mixed together • the HOC call is usually the last thing we see

Slide 17

Slide 17 text

Ok, back to hooks

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

Hooks • can only be used in function components • they represent a new mental model

Slide 20

Slide 20 text

Lifecycle methods

Slide 21

Slide 21 text

Basic hooks • useState for local state • useEffect for side-effects • useContext for applying context

Slide 22

Slide 22 text

import React from 'react' function MyComponent() { const [email, setEmail] = React.useState('') return ( { setEmail(event.target.value) }} "/> ) }

Slide 23

Slide 23 text

Stateless or function components?

Slide 24

Slide 24 text

import React from 'react' function MyComponent() { React.useEffect(() "=> { console.log('mounted') return () "=> { console.log('unmounted') } }, []) return "// ""... }

Slide 25

Slide 25 text

A must-read: A Complete Guide to useEffect by Dan Abramov

Slide 26

Slide 26 text

Additional hooks • useMemo for memoizing a computed value • useCallback for memoizing a function reference • etc. https://reactjs.org/docs/hooks-reference.html

Slide 27

Slide 27 text

import React from 'react' import { computeExpensiveValue } from './utils/slow' function MyComponent({ id }) { const value = React.useMemo(() "=> { return computeExpensiveValue(id) }, [id]) return "// ""... }

Slide 28

Slide 28 text

Read before memoizing • One simple trick to optimize React re-renders • When to useMemo and useCallback

Slide 29

Slide 29 text

Custom hooks

Slide 30

Slide 30 text

import React from 'react' function useModal() { const CLASS_NAME = 'modal-open' React.useEffect(() "=> { document.body.classList.add(CLASS_NAME) return () "=> { document.body.classList.remove(CLASS_NAME) } }, []) }

Slide 31

Slide 31 text

Custom hooks recipes: usehooks.com

Slide 32

Slide 32 text

eslint-plugin-react-hooks

Slide 33

Slide 33 text

yarn install "--save-dev eslint-plugin-react-hooks module.exports = { plugins: [ 'react-hooks', ], rules: { 'react-hooks/rules-of-hooks': 'error', 'react-hooks/exhaustive-deps': 'warn', } }

Slide 34

Slide 34 text

No content

Slide 35

Slide 35 text

import React from 'react' import AnotherComponent from './AnotherComponent' function MyComponent({ id }) { const onClick = React.useCallback(() "=> { "// do something with id }, [id]) return ( ) }

Slide 36

Slide 36 text

const onClick = React.useCallback(() "=> { "// do something with id }, [id])

Slide 37

Slide 37 text

const onClick = React.useMemo(() "=> { return () "=> { "// do something with id } }, [id])

Slide 38

Slide 38 text

import React from 'react' import AnotherComponent from './AnotherComponent' function MyComponent({ id }) { const onClick = React.useCallback(() "=> { "// do something with id }, [id]) return ( ) }

Slide 39

Slide 39 text

Does AnotherComponent need reference equality?

Slide 40

Slide 40 text

import React from 'react' function AnotherComponent({ onClick }) { "// expensive rendering } export default React.memo(AnotherComponent)

Slide 41

Slide 41 text

Pros • less typing, more thinking • reusing behavior is nicer • no need for classes anymore…?

Slide 42

Slide 42 text

Cons • unlearning lifecycle methods • are there any more cons? that’s up to you

Slide 43

Slide 43 text

Questions? @silvenon