【问题标题】:React hooks state ManagementReact 钩子状态管理
【发布时间】:2020-06-24 15:13:24
【问题描述】:


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

这是我的功能: 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”。
但我不知道它是否是最优的。是吗?

【问题讨论】:

    标签: javascript reactjs react-hooks


    【解决方案1】:

    Rules of Hooks 所述,您不能在循环\回调中使用钩子。

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

    尝试将use 前缀添加到您的自定义挂钩名称并查看警告:

    React Hook useState 不能在回调中调用。 React Hooks 必须在 React 函数组件或自定义 React Hook 函数中调用。 (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 };
      });
    };
    

    另外,这个sn-p的bug很少:

    1. stateinitialState 将在每次渲染时重新分配。
    2. 使用不带返回值的map
    3. 如上所述的 Hooks 规则。
    4. 不是错误,而是在那些 sn-ps 中,您似乎试图在函数中使用来自类的 OOP 方法,而钩子会激发您进行函数式编程。

    【讨论】:

    • 在答案中指出得很好。如前所述,您可以使用基于类的组件。加上功能单元测试在这里成为一个挑战!
    【解决方案2】:

    补充丹尼斯·瓦什所说的话。

    这一行:state.count.set(state.count.get() + 1) 可以很容易地替换为state.count.set(prevState =&gt; { 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 是怎么回事?它没有在任何地方使用过。

    【讨论】:

    • 是最优的吗?我认为它使用每个 setState 上的状态重新渲染每个组件...
    • 是的,这是预期的行为。
    猜你喜欢
    • 2020-04-10
    • 2019-09-22
    • 2020-05-23
    • 2020-07-13
    • 2020-04-29
    • 2017-11-26
    • 2021-09-29
    • 2020-04-26
    • 2019-11-28
    相关资源
    最近更新 更多