我的代码有效,但我有一个最佳实践问题:我在状态中有一个对象数组,用户交互将一次更改一个对象的值.据我所知,我不应该直接改变状态,我应该总是使用setState.如果我想以任何代价避免这种情况,我将通过迭代深度克隆数组,并更改克隆.然后将状态设置为克隆.在我看来,避免改变我以后会改变的状态只会降低我的表现.
详细版本:
this.state.data是一个对象数组.它代表论坛中的主题列表,收藏夹按钮将切换,调用clickCollect().由于我在状态中有一个数组,当我更改一个项的is_collected属性时,我需要创建一个要使用的数组的副本,并在更改为新值后,我可以将其设置为状态.
Run Code Online (Sandbox Code Playgroud)var data = this.state.data.slice(0); data[index].is_collected = !data[index].is_collected; this.setState({data: data});
var data = this.state.data:这会将指针复制到数组,push(),shift()等会直接改变状态.双方data并this.state.data会受到影响.
var data = this.state.data.slice(0):这使得浅层克隆,推送和移位不会改变状态,但在我的克隆中,我仍然有指向状态数组元素的指针.所以,如果我改变data[0].is_collected,this.state.data[0].is_collected也会改变.这发生在我打电话之前setState().
通常我应该这样做:
Run Code Online (Sandbox Code Playgroud)var data = []; for (var i in this.state.data) { data.push(this.state.data[i]); }
然后我更改index的值,当它为false时将其设置为true,否则为true时:
Run Code Online (Sandbox Code Playgroud)data[index].is_collected = !data[index].is_collected;
并改变状态:
Run Code Online (Sandbox Code Playgroud)this.setState({data: data});
考虑我的阵列相对较大或非常大,我想这次迭代会降低我的APP的性能.如果我知道这是出于任何原因的正确方法,我会支付这笔费用.但是,在这个函数(clickCollect)中,我总是将新值设置为状态,我不是在等待一个错误的API响应,它会说停止进行更改.在所有情况下,新值都将进入状态.实际上我setState只调用UI再次渲染.所以问题是:
for var i in ...).slice(0)如果我的数组包含对象,那么生成浅层clone()是否有意义?正在对数组内部的对象进行更改,因此浅层克隆仍会更改我的状态,就像copy(data = this.state.data)一样.为简单起见,我的代码被简化并且API调用被删除.
这是一个初学者的问题,所以也欢迎采用完全不同的方法.或链接到其他问答.
Run Code Online (Sandbox Code Playgroud)import React from …
我正在使用 React 和 TypeScript。当我使用 map() 遍历数组时,似乎并不总是检查类型。在下面的示例中,我将字符串“more”传递给 eachItem 函数,其中需要数字。但是没有抛出错误:
function eachItem(val: number, i: number) {
return Number(val) / 2;
}
const arr = [4, "more", 6];
arr.map(eachItem);
Run Code Online (Sandbox Code Playgroud)
我想我明白为什么会发生这种情况,但我的问题是如何在 map 函数上进行严格的输入,以便在传入字符串时出现此错误:
“字符串”类型的参数不能分配给“数字”类型的参数
为什么没有抛出错误是因为我正在给 map() 一个回调。这个 map() 需要这种类型的回调:
'(value: string | number, index: number, array: (string | number)[]) => Element'
Run Code Online (Sandbox Code Playgroud)
我正在提供这种类型的回调:
'(item: number, i: number) => Element'
Run Code Online (Sandbox Code Playgroud)
因此,与其检查 'number' 是否包含 'string | number', TypeScript 检查是否 'string | number' 包括 'number' 并发现它是真的。我的逻辑说我们需要一个错误,因为我在只允许数字的地方传递“更多”。TypeScript 的逻辑说没有错误,我正在传递一个允许数字的函数,其中允许允许字符串和数字的函数。这似乎不是什么大问题,但是当您的类型是联合时,您会在不应该出现的情况下出现错误。这是一个例子,结果错误:
interface IMoney {
cash: number;
} …Run Code Online (Sandbox Code Playgroud)