你如何将一个React useState挂钩分解成一个命名空间?

时间:2019-06-16 21:48:20

标签: javascript reactjs

根据个人喜好,我将React道具包装在名称空间中。它可以帮助我整理不同道具的来源。

使用 handleMonthIncrement: function(arg) { // update month and year this.incrementMonth(); // update calendar let calendarApi = this.$refs.fullCalendar.getApi(); calendarApi.next(); // updateCurrentSummary (mapped to store) this.updateCurrentSummary(); } 钩子,我正在这样做。

useState

用于状态设置的语法是否更简洁?

我的失败尝试是

function MyComponent() {
  const [todoCount, setTodoCount] = useState(100);
  const [doneCount, setDoneCount] = useState(0);
  const myState = {
    todoCount,
    setTodoCount,
    doneCount,
    setDoneCount
  };

  return (
    <>
      <Text>Todo {myState.todoCount}</Text>
      <Text>Done {myState.doneCount}</Text>
    </>
  );
}

2 个答案:

答案 0 :(得分:0)

听起来像您在custom hook中可以做的事情的类型,例如

 function useMappedState(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

理论中,这应该可以为您提供所需的信息,但是我尚未进行测试,因此请谨慎使用(例如,我不确定是否可以调用钩子)在迭代器中)。-此works fine

尽管,您所做的实际上是与useReducer类似的 ,可能值得尝试使用该钩子。

答案 1 :(得分:0)

当您需要管理复杂状态时,可以使用useReducer。它是一个钩子,除了初始状态外还接受减速器功能。减速器由您编写,用于将某些“动作”映射到状态变化。您可以将动作“分派”到reducer函数,以根据您指定的规则更新状态。 useState本身在内部调用useReducer

/* action = { type: string, payload: any type } */

function reducer(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
  }
}

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

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

您可以使用多个reducer映射到多个名称空间。