Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementation details of setStateVariable function in useState hook

We know that useState is a hook in FC that returns an array consists of two elements. The first one is a state variable and the second is a function to update the state variable.

const initialStateVariableValue = 0; // any primitive value
const [StateVariable, setStateVariable] = useState(initialStateVariableValue);

Here I would like to know what is the implementation details of setStateVariable function? How it is updating the state variable?

like image 781
Subrato Pattanaik Avatar asked Feb 26 '26 23:02

Subrato Pattanaik


1 Answers

If you check the implementation on React github you notice that useState is just calling useReducer with a basic reducer:

export function useState<S>(
  initialState: (() => S) | S,
): [S, Dispatch<BasicStateAction<S>>] {
  return useReducer(
    basicStateReducer,
    (initialState: any),
  );
}

So looking for the useReducer implementation, we see that the setter function is the dispatch function which changing depending on the lifecycle we currently in

export function useReducer<S, I, A>(
  reducer: (S, A) => S,
  initialArg: I,
  init?: I => S,
): [S, Dispatch<A>] {
  ...
    // dispatch depends on lifecycle
    return [..., dispatch];
  }
}

You can see the full useReducer implementation here.

For detailed implementation, you should try and Build your own React which eventually will lead to a simplified version of this hook:

function useState(initial) {
  const oldHook =
    wipFiber.alternate &&
    wipFiber.alternate.hooks &&
    wipFiber.alternate.hooks[hookIndex];
  const hook = {
    state: oldHook ? oldHook.state : initial,
    queue: []
  };

  const actions = oldHook ? oldHook.queue : [];
  actions.forEach(action => {
    hook.state = action(hook.state);
  });

  const setState = action => {
    hook.queue.push(action);
    wipRoot = {
      dom: currentRoot.dom,
      props: currentRoot.props,
      alternate: currentRoot
    };
    nextUnitOfWork = wipRoot;
    deletions = [];
  };

  wipFiber.hooks.push(hook);
  hookIndex++;
  return [hook.state, setState];
}

In simple words: every hook is saved in "React hooks array" (that's why the call order is essential because hooks saved in array's indexes - see Rules of Hooks), and depending on the hook's index, whenever called it mutates the state object associated with the current component.

like image 58
Dennis Vash Avatar answered Mar 02 '26 13:03

Dennis Vash



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!