2015-05-20 56 views
0

我有三个组件“MyApp”,“Candidate”和“Courses”,数据从MyApp传递到课程。 的数据是这样ReactJS:操作状态不会正确渲染子组件

var data = [{ 
    name : "azhar", 
    courses : ["Compilers", "Algorithms", "Data Structures"] 
}, { 
    name : "Jenny", 
    courses : ["Design", "UX"] 
}]; 

而且ReactComponents呈现为这样如下:

<MyApp> 
    <Candidate> 
    <Courses> 
    <Courses> 
     <Courses> 
    </Candidate> 
</MyApp> 

问题:有一个按钮添加新的候选人,当点击我补充新的候选的状态MyApp的。点击时,我看到子组件不会呈现正确的数据。

新增的jsfiddle:https://jsfiddle.net/69z2wepo/8587/

真的希望有人给出了很好的解释,因为这是一个简单的用例。

感谢

回答

1

当你创建一个JSX元素的数组就像您使用this.state.data.map()一样,您应该始终包含一个key属性,该属性对于阵列中的该位置是唯一的。请注意,它不应该像数组中的索引或候选人的名称那样改变(因为可能有重复)。

如果你对你的候选对象添加id财产,并创建一个新的ID,当你添加一个候选人,它应该工作:https://jsfiddle.net/qzy3sr6w/2/

这里有一个很好的解释:http://blog.arkency.com/2014/10/react-dot-js-and-dynamic-children-why-the-keys-are-important/

的TL;博士那篇文章是因为它适用于push而不适用于unshift是因为如果你没有指定key,React将使用数组的索引作为键(不完全正确,但足够接近)。并且,由于您将数组添加到开头,它将使用之前用于其他组件的索引0,这意味着新的第一个元素将获得第二个元素课程。

+1

我刚刚失去了一个小时的调试疯狂,我错过了失踪的'钥匙'。 – SM79

+0

这就是交配。谢谢。 –

0

我不认为这是一个好主意,react.state直接使用,因为你是在这里做什么:

this.state.data.unshift({ 
      name : "Alice", 
      courses : [] // No courses for her. 
}); 

更好地利用这样的额外变量:

var candidates = this.state.data; 

    candidates.push({ 
     name : "Alice", 
     courses : [] // No courses for her. 
    }); 

    this.setState({ 
     data : candidates 
    }); 

这里是一个JSFidle:https://jsfiddle.net/69z2wepo/8597/

+0

谢谢,这很酷。但是你正在将对象推向数据数组。如果你不改变(),它仍然没有工作。 –

+0

嗯,你是对的。让我看看。 – SM79