Skip to content Skip to sidebar Skip to footer

How Do You Destructure A React Usestate Hook Into A Namespace?

As a personal preference I wrap React props in namespaces. It helps me organize where different props come from. With the useState hook I'm doing this. function MyComponent() {

Solution 1:

Sounds like the type of thing you could do as part of a custom hook e.g.

functionuseMappedState(defaultState = {}) {
   const keys = Object.keys(defaultState);
   return keys.reduce((map, k) => {
     const fk = `set${k.charAt(0).toUpperCase()}${k.slice(1)}`;
     const [state, setState] = useState(defaultState[k]);
     map[k] = state;
     map[fk] = setState;
     return map;
   }, {});
 }
 ...
 const state = useMappedState({
   todoCount: 100,
   doneCount: 0
 });
 console.log(state.todoCount) // 100
 state.setTodoCount(5); // should set state of todoCount

In theory, this should give you what you want, but I've not tested so use with caution (e.g. I'm not even sure if hooks can be called can be called inside an iterator). - this works fine.

Although, what you are doing is really similar to what useReducer already does, might be worth some experimenting with that hook instead.

Solution 2:

When you need to manage complex state, useReducer is the goto. It is a hook which accepts a reducer function in addition to initial state. The reducer is written by you to map certain "actions" to changes in state. You can "dispatch" an action to the reducer function to update state according to the rules you specify. useState itself internally calls useReducer.

/* action = { type: string, payload: any type } */functionreducer(state, { type, payload }) {
  switch(type) {
    case'do-todo':
      return { doneCount: state.doneCount + 1, todoCount: state.todoCount - 1 }
    case'undo-todo':
      return { doneCount: state.doneCount - 1, todoCount: state.todoCount + 1 }
    default:
      return state
  }
}

functionApp() {
  const [ state, dispatch ] = useReducer(reducer, { todoCount: 100, doneCount: 0 }) 

  return (
    <><Text>Todo {state.todoCount}</Text><Text>Done {state.doneCount}</Text><ButtononClick={() => dispatch({ type: 'do-todo' })}>Do Todo</Button></>
  );
}

You can use multiple reducers to map to multiple namespaces.

Post a Comment for "How Do You Destructure A React Usestate Hook Into A Namespace?"