开发者问题收集

React hooks 状态管理

2020-03-12
121


我在我的 React 项目中使用 hooks。
我编写了一个函数来管理 hooks 中的状态。
但我不知道它是否是最佳的。

这是我的函数: mapStateToDOM.js

import {useState} from 'react';

const mspStateToDOM = (initialState, state) => {
    Object.keys(initialState).map(item => {
        let [current, setCurrent] = useState(initialState[item]);
        state[item] = {get: () => current, set: setCurrent};
    });
};
export default mspStateToDOM;

有了它,我可以使用 state.varName.get() 从状态中获取变量
我可以使用 state.varName.set(SOME_VALUE) 更改变量>

这是我的代码:

import React from 'react';
import mspStateToDOM from '../config/mapStateToDOM/mapStateToDOM';

const Counter = () => {
    const state = {};
    const initialState = {
        count: 5,
        count2: 6
    };
    mspStateToDOM(initialState, state);
    return (
        <div>
            <p>You clicked {state.count.get()} times</p>
            <button
                onClick={() => {
                    state.count.set(state.count.get() + 1);
                }}>
                Click Me!
            </button>
        </div>
    )
};
export default Counter;

这使代码更简洁、可读且更易于使用。我不必为每个变量定义一个 setter,也不必在代码中多次使用“useState”。
但我不知道它是否是最佳的。是吗?

2个回答

您不能在 loop\callback 中使用钩子,如 钩子规则 中所述。

因此,这样的代码容易出错, 您没有收到警告的唯一原因是 linter 无法猜测它是一个自定义钩子

尝试在您的自定义钩子名称中添加 use 前缀并查看警告:

React Hook useState cannot be called inside a callback. React Hooks must be called in a React function component or a custom React Hook function. ( react-hooks/rules-of-hooks )

const useMapStateToProps = (initialState, state) => {
  Object.keys(initialState).map(item => {
    let [current, setCurrent] = useState(initialState[item]);
    state[item] = { get: () => current, set: setCurrent };
  });
};

此外,此代码片段中还有一些错误:

  1. stateinitialState 将在每次渲染时重新分配。
  2. 使用 map 而不返回值。
  3. 如上所述的 Hooks 规则。
  4. 不是错误,但在这些代码片段中,您似乎试图在函数中使用来自类的 OOP 方法,而 hooks 会激励您进行函数式编程。

Edit gracious-bassi-1q3s6

Dennis Vash
2020-03-12

补充 Dennis Vash 所说的内容。

此行: state.count.set(state.count.get() + 1) 可以轻松替换为 state.count.set(prevState => { return prevState + 1 })

此外,我建议执行

const state = {};
const initialState = {
        count: 5,
        count2: 6
};

const Counter = () => {
    const [state, setState] = useState(initialState);
    return (
        <div>
            <p>You clicked {state.count} times</p>
            <button
                onClick={() => {
                    setState(prevState => ({ ...prevState, count: prevState.count + 1 }) );
                }}>
                Click Me!
            </button>
        </div>
    )
};

无需使事情过于复杂。

但是 count2 怎么了?它还没有在任何地方使用过。

jperl
2020-03-12