Skip to content

Instantly share code, notes, and snippets.

@vincicat
Last active January 8, 2020 13:04
Show Gist options
  • Save vincicat/55be061ba25d136bd4c6084a37685ba4 to your computer and use it in GitHub Desktop.
Save vincicat/55be061ba25d136bd4c6084a37685ba4 to your computer and use it in GitHub Desktop.
memo: react hooks

The Basic

import

import React, {useEffect} from 'react';

Pick your hooks

useEffect

  • for side effect like data fetching, or anything should be done in componentDidMount() or componentDidUpdate()
  • to mimic componentDidMount(), provide a empty array as deps array more
useEffect(() =>{
  console.log("mounted")
}, []);
  • remember to return a callback function to do cleanup, especially the effect function called subscription to avoid no-op (also work as componentDidUnmount()

useRef

  • create a accessable & mutable ref for parent
  • instance variable replacement [ref]
  • Pros: useRef will give you the same ref object on every render
  • Cons:
    • useRef doesn’t notify you when its content changes.
    • Mutating the .current property doesn’t cause a re-render.
    • "If you want to run some code when React attaches or detaches a ref to a node, you may want to use a callback ref instead." (doc)
useImperativeHandle
  • use to expose instance variables and methods for the ref exposed by useRef():
function FancyInput(props, ref) {
  const inputRef = useRef();
  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current.focus();
    }
  }));
  return <input ref={inputRef} {...props} />;
}
FancyInput = forwardRef(FancyInput); //react-dom

// On parent side
let inputRef;
button = <FancyInput ref={inputRef} />
inputRef.current.focus()
  • cloud be class member and member function replacement?

useMemo

  • avoid unneccessary re-computation by re-rendering by memorization
  • 'create' callback function must return a value (any)
  • can return react component
  • caution: if no deps array is provided, a new value will be computed on every render
  • caution: function as deps deprecedated. some reference code is no longer working example

see

useCallback
  • useCallback(fn, deps) is equivalent to useMemo(() => fn, deps)
  • This is useful when passing callbacks to optimized child components that rely on reference equality to prevent unnecessary renders (e.g. shouldComponentUpdate).

intro: link

further reading: link

useState

  • replacement of this.state
  • make good use of the first arg: if this is a function, this is the initializer
  • note: useState does not automatically merge update objects, if the object structure is deep, use useReducer() [ref]

useReducer

  • same as redux reducer
  • will cause less re-rendering

useContext

  • the Context Provider/Consumer API without wrapping a consumer:
  1. Have a Context to store data
  2. Have a to bind the Context to the
  3. Consumer component call useContext to access the context
  • Can replace redux store or provide global variable/subscription hub

Limitation

Limit to functional component and react hooks

Any class or pure function will cause eror

deps

  • deps array is used to include the variable which will trigger recomputation when they changes
  • changes detection is done by Object.is() (basic heuristic)
  • but that variable can be comparator's result
useEffect(
  () => {
    // ...
  },
  [compare(a, b)]
);

[source]

Advance

Lift up and pass down state

aka. "Send data from child to parent component" (Lift up)

The idea: "When the child called setState(newState), do a callback (cb(newState)), or, dispatch(newState)"

  1. dispatcher dispatch(newState) can be any reducer from useReducer() or useRedux()
  2. dispatcher pass by props from parent, so child have minimial knowledge to parent

anther alternative:

  • useContext()
  • useRef + useImperativeHandle() (The DOM way)

Reference

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment