使用字符串动态响应 setState
Posted
技术标签:
【中文标题】使用字符串动态响应 setState【英文标题】:React setState dynamically using string 【发布时间】:2020-04-20 19:41:57 【问题描述】:如何在 React 组件中动态设置和存在状态字段?
我目前的尝试导致以下方法,但它在 TypeScript 中不起作用:
export interface MaskCompanyDetailState
fieldId: number;
export class MaskCompanyDetail extends React.Component<MaskCompanyDetailProps, MaskCompanyDetailState>
public constructor(props: any)
super(props);
// Set field defaults.
this.state =
fieldId: 0,
;
public componentDidMount()
const myField: string = 'fieldId';
const myVal: number = 123;
this.setState([myField]: myVal);
this.setState(myField: myVal);
来自 TSLint 的 this.setState([myField]: myVal);
的错误消息:
类型参数 ' [x: string]: number; ' 不可分配给“MaskCompanyDetailState |”类型的参数((prevState: Readonly, props: Readonly) => MaskCompanyDetailState | Pick<...>) |选择<...>'。 输入 ' [x: string]: number; ' 缺少“Pick”类型的以下属性:fieldId、fieldCompanyName、fieldStreetName、fieldStreetNumber 和 4 个以上。ts(2345)
来自 TSLint 的 this.setState(myField: myVal);
的错误消息:
类型参数 ' myField: number; ' 不可分配给“MaskCompanyDetailState |”类型的参数((prevState: Readonly, props: Readonly) => MaskCompanyDetailState | Pick<...>) |选择<...>'。 对象字面量只能指定已知属性,并且“myField”类型不存在于“MaskCompanyDetailState | ((prevState: Readonly, props: Readonly) => MaskCompanyDetailState | Pick<...>) |选择<...>'.ts(2345)
已经有帖子here了,但是我不知道如何应用建议的IState
接口。
【问题讨论】:
您想为对象添加属性吗?或者你想使用myField
变量的值来动态设置属性名?
为什么myField
键周围有引号?有点违背了计算属性的要点,['myField']: 123
与myField: 123
相同,我认为这不是您想要做的,我猜myField
是一个变量,在这种情况下它应该是[myField]: 123
我已通过指定初始问题并提供更多代码来更新帖子。
切向相关:“TSLint”指的是现已弃用的单独工具。您可能指的是“TypeScript”。
【参考方案1】:
在MaskCompanyDetailState
接口中添加如下字段——
[key: string]: any;
即,
interface MaskCompanyDetailState
... // existing fields
[key: string]: any;
这意味着您允许在您的状态中设置具有string
类型的键和any
类型的值的任何属性。
这就是您链接的post 所说的。这是一个 Index Signature
的例子,它是 Typescript 的一个特性。
不建议这样做,因为从长远来看,它会影响代码的可读性,并且团队中的其他人可能会滥用它。但除了重新考虑您的设计之外,我不知道有任何其他解决方案可以解决您的困境。
【讨论】:
是否可以设置readonly
以便可以读取/写入现有字段,但阻止在运行时创建新字段的可能性?
[key: string]: any;
部分是索引签名,而不是真正的属性。我已编辑我的答案以包含更多信息的链接。虽然您可以将其设置为 readonly
,但当您在代码中执行 this.setState([myField]: myVal);
时,您实际上是在运行时在状态中创建新的字段/属性。没有办法解决这个问题。
readonly
意味着您只能在状态上创建(并在数组的情况下进行变异)属性。 AFAIK,没有办法阻止人们在运行时使用Index Signature
创建新字段。我的建议是在MaskCompanyDetailState
中声明所有可能的字段,但将它们标记为可选,而不是使用Index Signature
。以上是关于使用字符串动态响应 setState的主要内容,如果未能解决你的问题,请参考以下文章
Flutter:setState 在第一次尝试时工作,但在响应 = 等待后没有工作