Maurice Wu
Published on

React-hooks-example

01 use-state

unidirectional flow and asynchronous state assignment

02 use-state-object

The state is immutable, it's read-only. You can't change the object state by updating the object's property.

And it does not re-render every time the setState function is called, cause you may update the same value as the current state. React will bail out without rendering in the scenario by comparing the new with the old value using the Object.is algorithm.

03 component did onload

We can subscribe to certain events in hooks. For instance, we can make use of React.useEffect passing as the second argument an empty array to simulate the didMounted event.

export function MyComponent() {
  React.useEffect(() => {
    console.log('component did mounted')
  }, [])
}

04 component unmounted

We can make use of React.useEffect returning a function to simulate the unmounted event.

export function MyComponent() {
  React.useEffect(() => {
    console.log('component did mounted')
    return () => {
      console.log('component unmounted')
    }
  }, [])
}

05 component update render

React.useEffect(() => {
    console.log("A. Called when the component is mounted and after every render");

+    return () =>
+      console.log(
+        "B. Cleanup function called after every render"
+      );
+  });

By calling React.useEffect without a second parameter, the code inside useEffectwill be triggered right when the component is ** just mounted and on any update**

(clean up function will be called right before the effect is triggered again)

06 ajax field change

import { useDebounce } from 'use-debounce';

export const MyComponent = () => {
  const [filter, setFilter] = React.useState("");
  const [debouncedFilter] =   useDebounce(filter, 500);
  const [userCollection, setUserCollection] = React.useState([]);

  // Load full list when the component gets mounted and filter gets updated
  React.useEffect(() => {
    fetch(`https://jsonplaceholder.typicode.com/users?name_like=${filter}`)
      .then((response) => response.json())
      .then((json) => setUserCollection(json));
}, [debouncedFilter]);

07 custom hook

reuse logic across multiple components

08 Pure components

Pure components will make a shallow comparison of the props and only rerender if changed. React.memo does the same trick.

09 Pure component callback

The function created inside components will always be different on each render. It will result in the child component rerendering if passing the function as the props of it.

The solution is React.useCallback passing the second argument an empty array.

export function MyComponent() {
  const onClick = useCallback(() => {}, [])
}

10 use-reducer

useReducer should be an effective approach to managing a rich state and various actions.

https://github.com/Lemoncode/react-hooks-by-example/blob/master/10-use-reducer/src/demo.tsx

11 use-context

share global data across the deep component tree.

12 set state func

An important issue to consider with hooks and functional components is that the functions are executed once and die ( hooks serve as data stores among other things), but if we make an asynchronous call, the closure principle will be applied and if we need to retrieve any state data it will just hold a frozen value from the past.

13 async closure

14 use ref dom

export function MyComponent() {
  const domRef = React.useRef(null)
  return <div ref={domRef}></div>
}

15 promise unmounted

_Warning: In React you cannot update the status of a dismounted component. It is a no-op, but it is an indication of a memory leak in your application. To fix this, cancel all subscriptions and asynchronous tasks in a cleanup function in a useEffect.

You can ignore the warning if setting the state on an unmounted component does not cause a memory leak, like when setting the state after a fetch request promise is resolved.

16 memo predicated

The second argument in React.memo indicates whether the component should be updated.

17 use debug value

export function MyComponent() {
  const [user, setUser] = React.useState('')
  React.useDebugValue(user !== '' ? `User ${user}` : 'No User')
  return <div>{user}</div>
}

This hook allows you to display a label for a custom hook.

18 Why did you update

The variables inside the parent component will re-create on every render. If passing that as child component props, the new variables will trigger the child component to re-render even if the values before and after are the same.