Upgrade to Pro — share decks privately, control downloads, hide ads and more …

React Hooks

React Hooks

Matija Marohnić

December 13, 2019
Tweet

More Decks by Matija Marohnić

Other Decks in Programming

Transcript

  1. 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
  2. class MyComponent extends React.Component { state = { email: ''

    } render() { return ( <input type="email" value={this.state.email} onChange={event "=> { this.setState({ email: event.target.value, }) }} "/> ); } }
  3. 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
  4. class MyComponent extends React.Component { constructor(props) static getDerivedStateFromProps(props, state) render()

    componentDidMount() shouldComponentUpdate(nextProps, nextState) getSnapshotBeforeUpdate(prevProps, prevState) componentDidUpdate(prevProps, prevState, snapshot) componentWillUnmount() }
  5. Pros • transparency • descriptive method names • API is

    well documented • fine-grained control • easily target exact moment in the lifecycle
  6. Cons • no way to escape the complexity • memorizing

    common pitfalls like endless loops • spreading a single feature across multiple methods
  7. import email from './hocs/email' function MyComponent({ email, handleEmailChange }) {

    return ( <input type="email" value={email} onChange={handleEmailChange} "/> ) } export default email(MyComponent)
  8. Cons • readability • all props are mixed together •

    the HOC call is usually the last thing we see
  9. Hooks • can only be used in function components •

    they represent a new mental model
  10. Basic hooks • useState for local state • useEffect for

    side-effects • useContext for applying context
  11. import React from 'react' function MyComponent() { const [email, setEmail]

    = React.useState('') return ( <input type="email" value={email} onChange={event "=> { setEmail(event.target.value) }} "/> ) }
  12. import React from 'react' function MyComponent() { React.useEffect(() "=> {

    console.log('mounted') return () "=> { console.log('unmounted') } }, []) return "// ""... }
  13. Additional hooks • useMemo for memoizing a computed value •

    useCallback for memoizing a function reference • etc. https://reactjs.org/docs/hooks-reference.html
  14. import React from 'react' import { computeExpensiveValue } from './utils/slow'

    function MyComponent({ id }) { const value = React.useMemo(() "=> { return computeExpensiveValue(id) }, [id]) return "// ""... }
  15. Read before memoizing • One simple trick to optimize React

    re-renders • When to useMemo and useCallback
  16. 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) } }, []) }
  17. 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', } }
  18. import React from 'react' import AnotherComponent from './AnotherComponent' function MyComponent({

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

    "// do something with id } }, [id])
  20. import React from 'react' import AnotherComponent from './AnotherComponent' function MyComponent({

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

    expensive rendering } export default React.memo(AnotherComponent)
  22. Pros • less typing, more thinking • reusing behavior is

    nicer • no need for classes anymore…?