允许typescript编译器仅在一个react状态属性上调用setState
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了允许typescript编译器仅在一个react状态属性上调用setState相关的知识,希望对你有一定的参考价值。
我正在将一个带有React的Typescript用于一个项目。 Main组件通过此接口获得传递状态。
interface MainState {
todos: Todo[];
hungry: Boolean;
editorState: EditorState; //this is from Facebook's draft js
}
但是,下面的代码(仅限摘录)将无法编译。
class Main extends React.Component<MainProps, MainState> {
constructor(props) {
super(props);
this.state = { todos: [], hungry: true, editorState: EditorState.createEmpty() };
}
onChange(editorState: EditorState) {
this.setState({
editorState: editorState
});
}
}
编译器抱怨说,在我只尝试为一个属性设置State的onChange
方法中,todos
类型中缺少属性hungry
和属性{ editorState: EditorState;}
。换句话说,我需要在onChange
函数中设置所有三个属性的状态以使代码编译。为了编译,我需要做
onChange(editorState: EditorState){
this.setState({
todos: [],
hungry: false,
editorState: editorState
});
}
但是没有理由在代码中设置todos
和hungry
属性。在typescript / react中只调用一个属性的正确方法是什么?
Edit
反应的定义已更新,setState
的签名现在为:
setState<K extends keyof S>(state: Pick<S, K>, callback?: () => any): void;
其中Pick<S, K>
是在Typescript 2.1中添加的内置类型:
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
}
有关更多信息,请参阅Mapped Types。 如果您仍然有此错误,那么您可能需要考虑更新您的反应定义。
Original answer:
我面对同样的事情。
我设法解决这个令人讨厌的问题的两种方法是:
(1)铸造/断言:
this.setState({
editorState: editorState
} as MainState);
(2)将接口字段声明为可选:
interface MainState {
todos?: Todo[];
hungry?: Boolean;
editorState?: EditorState;
}
如果有人有更好的解决方案,我会很高兴知道!
Edit
虽然这仍然是一个问题,但有两个关于新功能的讨论将解决这个问题: Partial Types (Optionalized Properties for Existing Types) 和 More accurate typing of Object.assign and React component setState()
显式更新状态,例如计数器
this.setState((current) => ({ ...current, counter: current.counter + 1 }))
我认为最好的方法是使用Partial
以下列方式声明您的组件
class Main extends React.Component<MainProps, Partial<MainState>> {
}
部分自动将所有键更改为可选。
编辑:请勿使用此解决方案,请更喜欢https://stackoverflow.com/a/41828633/1420794有关详细信息,请参阅注释。
现在扩展运算符已经在TS中出货,我的首选解决方案是
this.setState({...this.state, editorState}); // do not use !
通过使用setState
进行参数化,我们可以告诉<'editorState'>
它应该期望哪个字段:
this.setState<'editorState'>({
editorState: editorState
});
如果要更新多个字段,可以像这样指定它们:
this.setState<'editorState' | 'hungry'>({
editorState: editorState,
hungry: true,
});
虽然它实际上会让你逃脱只指定其中一个!
无论如何使用最新的TS和@types/react
都是可选的,但它们引导我们......
如果你想使用动态密钥,那么我们可以告诉setState
特别没有字段:
this.setState<never>({
[key]: value,
});
并且如上所述,如果我们通过额外的字段,它不会抱怨。
(Qazxswpoi)
以上是关于允许typescript编译器仅在一个react状态属性上调用setState的主要内容,如果未能解决你的问题,请参考以下文章
仅在 typescript React 中对数组的最后一个索引进行样式设置?
使用 Typescript 不允许 React createContext(null)?
Create React App 如何允许 Array.prototype.at() 而 TypeScript 不允许?
React + Redux-Observable + Typescript - 编译,参数不可分配错误