gpt4 book ai didi

reactjs - 使用 TypeScript : why is the type for the state lost when useState with a callback as the updater 使用react

转载 作者:行者123 更新时间:2023-12-03 14:44:41 26 4
gpt4 key购买 nike

首先,您将看到的代码片段是一个人为的示例。我只是好奇为什么打字不起作用。

interface MyState {
a: boolean;
b: number;
}

const defaultState: MyState = {
a: false,
b: 1
};

const keys = Object.keys(defaultState) as Array<keyof MyState>;

export default function App() {
const [myState, setMyState] = React.useState<MyState>(defaultState);

React.useEffect(() => {
keys.forEach((key) => {
setMyState((prev) => ({
...prev,
[key]: "lol". // should've given an error but it didn't
}));
});
}, []);

所以我有一个 defaultState以及在组件外部定义的键列表。在 useEffect 中,我使用 key 来更新状态(现在它只是将每个值都更改为“lol”)。我在 setMyState 中传递了一个回调作为更新程序它返回的应该是新状态。但是在这里我将值设置为字符串,这违反了我的接口(interface) MyState .
我想知道为什么它没有触发错误
这是一个现场演示: https://codesandbox.io/s/sweet-dewdney-u83id?file=/src/App.tsx
没有反应的最小示例: Playground

最佳答案

问题不在于使用回调来更新状态——这很好。问题是,当您使用动态键设置对象的属性时, typescript 不知道该键的值对于任何给定的循环迭代是什么,更不用说它的值应该是什么类型了。所以你需要告诉它。您需要使用泛型动态键入您的 key 。有一篇很棒的文章 right here .

  function updateValue<T extends keyof MyState, K extends MyState[T]>(
name: T,
value: K
) {
setMyState(prev => ({ ...prev, [name]: value }));
}

React.useEffect(() => {
keys.forEach((key) => {
updateValue(key, "lol");
});
}, []);
Here is a working codesandbox
Working Typescript playground
完全按照应有的方式给出错误。
进一步的思考:
这有一些有趣的怪癖。如果将值设置为界面上的可能值之一怎么办?
keys.forEach((key) => {
updateValue(key, 4); // <---- no error, but there should be
});
理论上,这也应该抛出一个错误,因为 key可能是 a ,在这种情况下类型不匹配。 TypeScript 不会抛出错误。但是,如果您指定仅在 key === 'a' ,错误确实发生:
keys.forEach((key) => {
if (key === 'a'){
updateValue(key, 4); // <---- typechecking error occurs
}
});
在后一种情况下, typescript 足够聪明,可以知道 key 是否为 a。 ,类型必须是数字。但是在前一种情况下,当您尝试分配与界面上的一种类型(但不是全部类型)匹配的值时,我们可能会看到一个错误,或者达到了 typescript 的限制。

关于reactjs - 使用 TypeScript : why is the type for the state lost when useState with a callback as the updater 使用react,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63733156/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com