【问题标题】:Is this the safest, most correct way to change an object state variable in React?这是在 React 中更改对象状态变量的最安全、最正确的方法吗?
【发布时间】:2021-11-10 04:30:18
【问题描述】:

以下代码有效,即成功更新对象状态变量:

import { useState } from 'react'
import './App.css';

function App() {
    const [config, setConfig] = useState({
        status: "online",
        maxFiles: 99
    });

    const addConfigEntry = () => {
        setConfig(n => {
            const n2 = { ...n };
            n2.errors = 0;
            return n2;
        })
    };
    return (
        <div className="App">
            <button onClick={addConfigEntry}>Add a Entry</button>
            <ul>
                {Object.entries(config).map((entry, index) => {
                    return (
                        <li key={index}>{entry[0]} = {entry[1]}</li>
                    )
                })}
            </ul>
        </div>
    );
}

export default App;

但是我收到了来自 TypeScript 的警告,这让我认为这不是更新对象变量的最佳方式:

是否有更正确、更符合 React 的方式来更新对象变量?

附录

请注意,这不起作用(回复评论):

setConfig({ ...config, errors: 0 }); // will not be added!
setConfig({ ...config, errors2: 0 });

【问题讨论】:

  • setConfig({ ...config, errors: 0 });
  • 但是您还没有向您的州声明类型。我假设这就是您收到警告的原因。 stackoverflow.com/questions/53650468/… 您可以声明您的状态类型,带有可选错误,然后您的代码应该可以工作,或者在状态初始化期间将 errors 分配为空值。
  • @zerkms 但该解决方案只能工作一次,如果您像这样调用 setConfig 两次,第一次更改将被覆盖,请参阅上面的附录
  • @EdwardTanguay 我只评论了你提供的代码,我无法预测你还有什么想法 :shrug: 对于一个电话 - 这是完全有效的。
  • @zerkms 我认为是这样,因为确实如此。 :-) 试试看。只有最后一个 setConfig 会起作用(在大多数情况下)。您需要使用更新程序功能来克服这个问题,就像我的原始代码一样。我相信这是一个异步问题。

标签: javascript reactjs typescript state use-state


【解决方案1】:

当你说,

const [config, setConfig] = useState({
        status: "online",
        maxFiles: 99
    });

TypeScript 根据您传递的初始状态对象推断配置的类型。所以,它认为config 看起来像:

type InferredConfig = {
  status: string;
  maxFiles: number;
}

请注意,解释类型中没有 errors,这就是您看到错误的原因。所以,我们需要明确地告诉类型。

您需要定义适当的type。这是一种方式:

import { useState } from 'react'
import './App.css';

// 1. We are defining the type, that *may* have errors prop
type Config = {
  status: string;
  maxFiles: number;
  errors?: number;
}

function App() {
    // 2. tell `useState` that it manages an object of type `Config`
    const [config, setConfig] = useState<Config>({
        status: "online",
        maxFiles: 99
    });

    const addConfigEntry = () => {
        setConfig(n => {
            const n2 = { ...n };
            n2.errors = 0;  // 3. No error
            return n2;
        })
    };
    return (
        <div className="App">
            <button onClick={addConfigEntry}>Add a Entry</button>
            <ul>
                {Object.entries(config).map((entry, index) => {
                    return (
                        <li key={index}>{entry[0]} = {entry[1]}</li>
                    )
                })}
            </ul>
        </div>
    );
}

export default App;

【讨论】:

    猜你喜欢
    • 2023-01-03
    • 2021-09-14
    • 2020-11-11
    • 1970-01-01
    • 2013-08-13
    • 1970-01-01
    • 1970-01-01
    • 2017-08-23
    • 2017-04-27
    相关资源
    最近更新 更多