如何在React中更改Component项的位置?
除非我误解了它,否则React会按key
列出项目列表项目,该项目由data-reactid
在DOM中表示,但我不知道如何修改key
1}}页面上的组件。
即。如何抓取组件,更改它key
,然后触发渲染,以便重新排序的列表按照您设置的顺序呈现?
e.g。在下面的代码示例中,单击Click me
链接时,第一个列表项将与最后一个列表项交换。
理想情况下,此功能允许您动态重新排序/重定位页面上的任何组件,而不会更改render
方法中组件的顺序。
以下是整个项目所在的仓库的链接:https://github.com/bengrunfeld/gae-react-flux-todos
var TodoBox = React.createClass({
render: function(){
return (
<div className="todo-container">
<h4>GAE React Flux Todos</h4>
<TodoList data={this.state.data} />
</div>
)
}
});
var TodoList = React.createClass({
changePosition: function(e){
// Change position of list item (e.g. to top/certain position/end of list)
},
render:function(){
var todoNodes = this.props.data.map(function(todo) {
return (
<Todo key={todo.id} id={todo.id}>
{todo.todoText}
</Todo>
);
});
return (
<form className="todoList">
{todoNodes}
<a onClick={this.changePosition}>Click me</a>
</form>
)
}
});
var Todo = React.createClass({
render:function(){
return (
<div className="todoItem">
<input type="text" className={this.props.id} onChange={this.checkInput} defaultValue={this.props.children} ref="todoItem"/>
</div>
)
}
});
答案 0 :(得分:7)
key
道具并非用于对元素进行排序,而是用于在不同的render
调用之间进行协调。具有相同key
的元素将不会被重新渲染,而是相互区分,以便最佳地更新DOM。见Reconciliation
如果你想重新排序元素,你需要在你的render
方法(todoNodes
)中更改你在JSX或你作为孩子传递的元素数组中的位置。
在您的情况下,您可以在this.props.data
组件状态下制作TodoList
的副本,然后使用changePosition
之类的内容在this.setState({data: reorderedData})
方法中更新该副本。制作该副本的好地方是getInitialState
。
然后会再次调用render
的{{1}}方法,然后映射新重新排序的TodoList
以创建一系列this.state.data
元素喜好。
但是,请注意props in getInitialState
is an anti-pattern。由于您的数据处于Todo
组件的状态,因此避免这种情况的方法是在TodoBox
方法中调用TodoList
组件this.props.onReorder(reorderedData)
。然后,您的changePosition
组件可以将事件处理程序传递给其TodoBox
子节点,并在调用此处理程序时使用新数据更新其状态。
TodoList
答案 1 :(得分:0)
键用于其他内容,而不是用于排序。 React使用key
来优化其内部Virtual DOM操作。这意味着你告诉React“无论这些兄弟姐妹的顺序如何,个别兄弟姐妹仍然被这把钥匙识别出来”。这就是React如何知道它是应该通过重用旧的来预先添加,插入,删除或追加新的兄弟姐妹,而不会不必要地扔掉东西。
关于排序问题:要更改兄弟姐妹的顺序,只需对JavaScript数组this.props.data
进行排序。