981377660LMT / ts

ts学习
6 stars 1 forks source link

如何对对象的每个key设置对应的react hooks #423

Open 981377660LMT opened 8 months ago

981377660LMT commented 8 months ago

在 React Hook 中,你不能在循环、条件或嵌套函数中调用 Hook,因为这可能会导致 React 无法正确地保存 Hook 的状态。这是 React Hook 的一个基本规则,被称为 "Hook 规则"。

在你的代码中,你试图在 forEach 循环中调用 useState Hook,这是不被允许的。如果你想为对象的每个属性创建一个状态,你应该在组件的顶层一次性创建一个状态对象,而不是为每个属性单独创建一个状态。

下面是一个修改后的例子:

const useDropdownGroupVisibility = <S extends Record<string, boolean>>(
  initState: S
): DropdownGroupVisibility<S> => {
  const [state, setState] = useState(initState);

  const setters = {} as { [K in keyof S as `set${Capitalize<string & K>}`]: (value: boolean) => void };

  for (const key in state) {
    setters[`set${capitalize(key)}`] = (value: boolean) => {
      setState(prevState => ({ ...prevState, [key]: value }));
    };
  }

  return { ...state, ...setters };
};

function capitalize(str: string) {
  return str.charAt(0).toUpperCase() + str.slice(1);
}

在这个例子中,我们一次性创建了一个状态对象 state,然后为每个属性创建了一个 setter 函数,这个函数会更新对应的状态。注意,我们使用了函数式的 setState,这是因为状态更新可能是异步的,直接使用 state[key] 可能会得到过期的状态。