Skip to main content

React Hooks

useState

The fundamental of storing information. useState hook allow you to create local state returning you both the value that you can access as well as a setter to modify the value. The modification of the state will trigger a re-rendering of the component.

A simple example of using state would be just a counter with a button that you can click an increment on.

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </div>
  );
}

useEffect

useEffect replaces the old lifecycle method in react like componentDidMount, componentDidUpdate, componentWillunmount. You can provide a callback method to run whenever the condition triggers. The condition is specify through the second parameter which is called the dependency array.

  • [] -> Whenever the component is mounted (The component has been loaded into the DOM)
  • no array -> Run after every single render
  • [state] -> Monitor a state so that whenever the state changes the method will be invoked

This is just a more extensive example of on how to use useEffect to trigger the update to displayString to append an extra pipe character whenever you increment by pressing the button. As you can see the button is not directly affecting the displayString but rather through the side effects of the hook.

function Counter() {
    
    let [counter, setCounter] = useState(0);
    let [displayString, setDisplayString] = useState("|")
    
    function increment() {
        setCounter(counter + 1);
    }
    
    useEffect(() => {
        setDisplayString(displayString + "|")
    }, [counter])
    
    return (
        <>
            <p>{displayString}</p>
            <button onClick={increment}>Increment</button>
        </>
    )
}

export default function SidePage() {
    return (
        <div>
            <Counter />
        </div>
    )
}

useContext

useContext solve one of the common problem that you might encounter when using React which is passing states around from the parent to deeply nested children.

Say the state is held by the highest parent and you would need to pass the state to one of the deeply nested children in order for it to display the value properly.

In React the manner of passing props deeply down to one of the child component is called props drilling.

You can see from this example that the Parent had to pass the value as prop through ChildA and then from ChildA to ChildB in order to display the value. Wouldn't it be easier if ChildB was able to just access the value directly from the Parent? With useContext hook you can!

function Parent() {
    let [value, setValue] = useState("Display from me nested Child B");
    
    return (
        <ChildA display={value} />
    )
}

function ChildA({display}) {
    return (
        <>
            <p>Child A</p>
            <ChildB display={display} />
        </>
    )
}

function ChildB({display}) {
    return (
        <p>{display}</p>
    )
}

export default function SidePage() {
    return (
        <div>
            <Parent />
        </div>
    )
}

In order to leverage useContext you must first create the context through the createContext and then wrap your child component that would like to have access to those states through the context provider.

function Parent() {
    let [display, setDisplay] = useState("Display from me nested Child B");
    
    return (
        <ParentContext value={display}>
            <ChildA />
        </ParentContext>
    )
}

function ChildA({display}) {
    return (
        <>
            <p>Child A</p>
            <ChildB />
        </>
    )
}

function ChildB() {
    let display = useContext(ParentContext);
    
    return (
        <p>{display}</p>
    )
}

export default function SidePage() {
    return (
        <div>
            <Parent />
        </div>
    )
}

With the ParentContext.Provider you set the value that you would like to set within context through the value attribute. In this case we are sharing the display state. Now once you wrap the component that you would like to have access to state, all of the children would be able to have access to the context by calling useContext hook.

As you can see within ChildB component we don't need the prop anymore, we can just access it through the context block.

Context can also be nested, if a component is nested in nested context then it will be using the closest context provider for resolving the value.

 

 

useReference