Javascript React JSX动态更改组件的状态。最佳做法及其原因
我是React的新手,正在关注youtube上的一段视频,并在上面添加了更多内容 我有一个按钮,当点击时,它会降低对象的Javascript React JSX动态更改组件的状态。最佳做法及其原因,javascript,reactjs,jsx,Javascript,Reactjs,Jsx,我是React的新手,正在关注youtube上的一段视频,并在上面添加了更多内容 我有一个按钮,当点击时,它会降低对象的值。在视频中,教师将状态复制到一个新数组中,找到项目的索引,执行所需的操作,然后使用this.setState() 这是我用来练习的硬编码状态。我希望当单击按钮时,值减少1,除非该值小于或等于0 state = { counters: [ { id: 1, name: "Drink 1", value: 4 }, { id
值。在视频中,教师将状态复制到一个新数组中,找到项目的索引,执行所需的操作,然后使用this.setState()
这是我用来练习的硬编码状态。我希望当单击按钮时,值
减少1,除非该值小于或等于0
state = {
counters: [
{ id: 1, name: "Drink 1", value: 4 },
{ id: 2, name: "Drink 2", value: 0 },
{ id: 3, name: "Drink 3", value: 0 },
{ id: 4, name: "Drink 4", value: 0 },
],
};
//and what I'm passing down to other components:
{this.state.counters.map((counter) => (
<Counter
key={counter.id}
counter={counter}
onDeletion={this.handleDeletion}
onIncrement={this.handleIncrement}
onDecrement={this.handleDecrement}
></Counter>
))}
状态={
计数器:[
{id:1,名称:“饮料1”,值:4},
{id:2,名称:“饮料2”,值:0},
{id:3,名称:“饮料3”,值:0},
{id:4,名称:“饮料4”,值:0},
],
};
//以及我要传递给其他组件的内容:
{this.state.counters.map((counter)=>(
))}
视频代码:
handleDecrement = (counter) => {
const counters = [...this.state.counters];
const indexOfCounters = counters.indexOf(counter);
counters[indexOfCounters] = { ...counter };
counters[indexOfCounters].value <= 0
? (counters[indexOfCounters].value = 0)
: counters[indexOfCounters].value--;
this.setState({ counters });
};
handleDecrement=(计数器)=>{
常量计数器=[…this.state.counters];
常量indexOfCounters=计数器。indexOf(计数器);
计数器[索引计数器]={…计数器};
计数器[indexOfCounters]。值{
counter.value我想您只是对更新计数器
数组而不是其中的对象(计数器
)的原因感到困惑
这是因为状态
应始终以不变的方式更新。在您的情况下,由于值
位于依次位于数组中的对象中,因此计数器
数组和计数器
对象在更新后应具有新的引用,以正确地通知React状态
已更改
在代码段中,this.setState(counter);
将用计数器
覆盖状态(因此其他计数器
将被删除),并且您还将对对象进行变异
如果您想使代码简洁一点,同时确保状态是不可变的,那么这里有一个替代方案:
handleDecrement = (counter) => {
this.setState(prevState => ({counters: prevState.counters.map(c => {
return (c.id === counter.id && c.value > 0) ? {...c, value: c.value - 1} : c;
})}));
};
在上面的代码段map
中,创建一个新的数组,并且{}
object literal语法创建了一个新的计数器
对象。在第二个示例中,您正在使用更新的整数值计数器
覆盖先前存储在状态中的对象。撇开实践不谈,您的更新方式是否意味着您对状态有不同的结构?@ramesheldy是的,w应该是正确的,我已经更新了我的代码,以显示我在计数器中传递的内容。这就是我获得命名的地方。@pilchard正确。并且视频片段覆盖了整个状态,而不仅仅是一个对象。这就是我在理解最佳方法时遇到的问题。哦,我明白了,你传递了一个对计数器对象的引用。问题在于,您通过直接更改引用的对象来改变状态。视频中的代码虽然冗长,但通过在状态对象的每个级别上进行克隆(通过扩展运算符)来避免改变状态。感谢您的解释,并非常感谢您的替代方案。
handleDecrement = (counter) => {
this.setState(prevState => ({counters: prevState.counters.map(c => {
return (c.id === counter.id && c.value > 0) ? {...c, value: c.value - 1} : c;
})}));
};