Javascript 反应渲染显示错误的元素

Javascript 反应渲染显示错误的元素,javascript,reactjs,Javascript,Reactjs,我开始学习如何用一个待办事项列表小项目做出反应。它有三个组成部分: Tasks是主要组件(App的子组件)。它呈现一个NewTask组件,该组件添加新任务,并包含一个包含所有要显示的Task组件的数组 NewTask是向列表中添加新任务的输入 任务表示任务 我的目标是在列表顶部添加一个新的任务,因此我认为最好的方法是将任务添加到任务数组的开头。问题是,当我执行此操作时,渲染无法正确显示任务,并重复最后一个任务。将任务添加到最后一个元素时,渲染结果是正确的。以下是一些图片: (左侧不

我开始学习如何用一个待办事项列表小项目做出反应。它有三个组成部分:

  • Tasks
    是主要组件(App的子组件)。它呈现一个
    NewTask
    组件,该组件添加新任务,并包含一个包含所有要显示的
    Task
    组件的数组

  • NewTask
    是向列表中添加新任务的
    输入

  • 任务
    表示任务

我的目标是在列表顶部添加一个新的
任务
,因此我认为最好的方法是将
任务
添加到
任务
数组的开头。问题是,当我执行此操作时,渲染无法正确显示任务,并重复最后一个任务。将任务添加到最后一个元素时,渲染结果是正确的。以下是一些图片:

(左侧不正确,右侧正确)

以下是三个组件的代码:

类任务扩展React.Component{
建造师(道具){
超级(道具);
此.state={
任务:[,,
, 
,
]
}
}
addNewTask=(文本)=>{
//this.setState({tasks:this.state.tasks.concat()})//添加到底部
this.setState({tasks:[].concat(this.state.tasks)})//添加到顶部
}
render(){
返回(
{this.state.tasks}
);
}
}
类NewTask扩展了React.Component{
建造师(道具){
超级(道具);
}
handleKeyPress=(事件)=>{
如果(event.key=='Enter'){
this.props.parentMethod(event.target.value);
}
}
render(){
返回(
);
}
}
类任务扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
已完成:false
}
}
变更状态(){
this.setState({completed:!this.state.completed});
}
render(){
让class_button=“check button”+(this.state.completed?'completed':'notcompleted');
让class_text=“posted task”+(this.state.completed?'completed':'not completed');
返回(
);
}
}

尝试将以下内容添加到顶部:

addNewTask = (text) => {
            this.setState(prevstate => {tasks: [<Task text={text}/>, ...prevState.tasks]
        }
你可以这样做:

this.state = {
           tasks: [<Task text="Comprar cerveza"/>, 
                   <Task text="Hacer la comida"/>, 
                   <Task text="Ver HIMYM"/>,
                   <Task text="Escuchar nuevo disco"/>]
}
    this.state = {
               tasks: ["Comprar cerveza", "Hacer la comida", "Ver 
    HIMYM","Escuchar nuevo disco"] 
}
{this.state.tasks.map((task, index) => <Task text={task} key={`${index}.${task}`}/>}
{this.state.tasks.map((任务,索引)=>}

错误并非来自我如何将新元素添加到数组中。问题是,如果我没有为每个元素指定唯一键,请将其检测为同一个组件,它将不会再次呈现。新组件如下所示:

class Tasks extends React.Component{

    constructor(props){
        super(props);

        this.state = {
            id: [0,1,2,3],
            tasks: ["Comprar cerveza", 
                    "Hacer la comida", 
                    "Ver HIMYM",
                    "Escuchar nuevo disco"]
        }
    }

    addNewTask = (text) => {
        // Add to top
        this.setState({ id: [this.state.id.length].concat(this.state.id),
                        tasks: [text].concat(this.state.tasks)})
    }

    render(){
        return (
            <div className="task-container">
                <NewTask parentMethod={this.addNewTask} text="New Task"/>
                {/* Create the task */}
                {this.state.tasks.map( (el,i) => {
                    return(
                        <Task id={this.state.id[i]} text={el}/>
                    );
                })}
            </div>
        );
    }
}
类任务扩展React.Component{
建造师(道具){
超级(道具);
此.state={
id:[0,1,2,3],
任务:[“Compar cerveza”,
“哈泽拉科米达”,
“Ver Himmy”,
“新埃斯库查尔迪斯科舞厅”]
}
}
addNewTask=(文本)=>{
//添加到顶部
this.setState({id:[this.state.id.length].concat(this.state.id),
任务:[text].concat(this.state.tasks)})
}
render(){
返回(
{/*创建任务*/}
{this.state.tasks.map((el,i)=>{
返回(
);
})}
);
}
}
类任务扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
已完成:false
}
}
变更状态(){
this.setState({completed:!this.state.completed});
}
render(){
让class_button=“check button”+(this.state.completed?'completed':'notcompleted');
让class_text=“posted task”+(this.state.completed?'completed':'not completed');
返回(
);
}
}

这对我不起作用。你能解释一下这句话吗?我注意到我有一个关于键的警告,所以我像你一样为每个元素指定了一个唯一的键。我在发布问题时对键一无所知。谢谢!
class Task extends React.Component{
    constructor(props){
        super(props);

        this.state = {
           completed: false
        }
    }

    changeState(){
        this.setState({completed: !this.state.completed});
    }

    render(){
        let class_button = "check-button " + (this.state.completed ? 'completed' : 'not-completed');
        let class_text = "posted-task " + (this.state.completed ? 'completed' : 'not-completed');

        return (
            <div className="task" key={this.props.id}>
                <button className={class_button} onClick={this.changeState.bind(this)}/>
                <input className={class_text} defaultValue={this.props.text}/>
            </div>
        );
    }
}