Codesandbox链接https://codesandbox.io/s/mjxrz2npzy
我正在创建一个应用程序,用户可以在其中单击“添加计时器”按钮来创建有限数量的自定义倒数计时器/倒数计时器,这些计时器在组件CustomTimerRow中定义。每行都有一个图标,如果单击它们,它将删除计时器。
我有以下包含行列表的父组件:
import React, { Component } from 'react';
import {connect} from 'react-redux';
import CustomTimerRow from './CustomTimerRow';
import AddRow from './AddRow';
const mapStateToProps = state => {
return {customTimers:state.clock.customTimers}
};
class ConnectedCustomTimers extends Component
{
constructor(props)
{
super(props);
this.buildCustomTimers = this.buildCustomTimers.bind(this);
}
buildCustomTimers()
{
let timerList = [];
let index = 0;
if(this.props.customTimers)
{
for(let t of this.props.customTimers)
{
timerList.push(<CustomTimerRow number={index++} timer={t}/>)
}
}
return timerList;
}
render()
{
const elems = this.buildCustomTimers();
const addRow = (this.props.customTimers.length < 8 ? <AddRow/>:<span/>);
return (<div>
{elems}
{addRow}
</div>
);
}
}
const CustomTimers = connect(mapStateToProps, null)(ConnectedCustomTimers);
export default CustomTimers
我的Redux存储针对计时器执行以下操作:
case constants.ADD_CUSTOM_TIMER:
return {...state,customTimers:[...state.customTimers,action.payload]};
case constants.REMOVE_CUSTOM_TIMER:
const newTimers = state.customTimers.slice();
newTimers.splice(action.payload, 1);
return {...state,customTimers:newTimers};
添加行时,一切工作都很好,但是,当我删除一行时,无论从中间选择要删除的行还是删除第一行,它总是从列表中删除最后一行。< / p>
当我添加日志记录时,一直到CustomTimers的渲染都看起来正确。 buildCustomTimers返回一个我希望看到的对象列表。但是一旦回报发生了,React完成了任务,我就会看到不同的结果。
我要添加和删除错误的组件吗?我同时使用状态更新和包含父项来确定要显示的内容,但似乎重新渲染更新的组件列表无法正常工作。
更新:我将代码更新为以下内容:
buildCustomTimers()
{
let timerList = [];
let index = 0;
if(this.props.customTimers)
{
for(let t of this.props.customTimers)
{
timerList.push(<li key={index++}><CustomTimerRow key={index++} timer={t}/></li>)
}
}
return timerList;
}
render()
{
const elems = this.buildCustomTimers();
const addRow = (this.props.customTimers.length < 8 ? <AddRow/>:<span/>);
return (<div><ul>
{elems}
</ul>{addRow}</div>
);
}
但这完全没有改变行为,因此我不相信列表和关键答案可能是正确的答案(尽管如果有其他方法也不能打折扣)
答案 0 :(得分:2)
错误可能出在您的CustomTimerRow代码中,但是当您在循环中创建组件列表时,必须添加“键”道具。 该密钥必须唯一。
如果您尝试:
<CustomTimerRow number={index++} timer={t} key={t.eventType} />
您会看到它正在运行。由于 t.eventType 不是唯一的,因此它不能作为您的确定键,但这向您展示了键的重要性。
答案 1 :(得分:0)
对我来说,解决方案是不使用重新定义的类对象更新tihs.setState(...),而仅使用parennt.removeChild(...)类进行更新。否则,仅删除js对象,并保留ul / li项目。