React.js: 如何更改组件项的位置
React.js: How do you change the position of a Component item
如何在 React 中更改组件项的位置?
除非我误解了,React orders list items by key
,在 DOM 中表示为 data-reactid
,但我不知道如何修改页面上 key
个组件。
即如何抓取组件,更改它的 key
,然后触发渲染,以便重新排序的列表按照您设置的顺序呈现?
例如在下面的代码示例中,当单击 Click me
link 时,第一个列表项将与最后一个列表项交换。
理想情况下,此功能允许您动态 reorder/relocate 页面上的任何组件,而无需更改 render
方法中组件的顺序。
这里是一个 link 到整个项目所在的 repo: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>
)
}
});
key
属性不用于对元素进行排序,而是用于在不同的 render
调用之间协调它。具有相同 key
的元素将不会是 re-rendered 而是相互区分以最佳地更新 DOM。参见 Reconciliation
如果你想重新排序元素,你需要改变它们在你的 JSX 中的位置,或者在你作为 children 在你的 render
方法中传递的元素数组中的位置 (todoNodes
) .
在您的情况下,您可以在 TodoList
组件状态下制作 this.props.data
的副本,然后在 changePosition
方法中使用 this.setState({data: reorderedData})
之类的内容更新该副本.制作该副本的好地方是 getInitialState
.
然后将再次调用 TodoList
的 render
方法,并且您将映射到新重新排序的 this.state.data
以创建有序的 Todo
元素数组随你喜欢。
但是,请注意 props in getInitialState
is an anti-pattern。由于您的数据存在于 TodoBox
组件的状态中,因此避免这种情况的一种方法是让 TodoList
组件在其 changePosition
方法中调用 this.props.onReorder(reorderedData)
。然后,您的 TodoBox
组件可以将事件处理程序传递给它的 TodoList
child,并在调用此处理程序时使用新数据更新其状态。
var TodoBox = React.createClass({
handleReorder: function(reorderedData) {
this.setState({data: reorderedData});
},
render: function(){
return (
<div className="todo-container">
<h4>GAE React Flux Todos</h4>
<TodoList data={this.state.data} onReorder={this.handleReorder} />
</div>
)
}
});
var TodoList = React.createClass({
changePosition: function(e){
// Change position of list item (e.g. to top/certain position/end of list)
// Create a copy of this.props.data and reorder it, then call
// this.props.onReorder to signal to the parent component that
// the data has been reordered
this.props.onReorder(reorderedData);
},
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>
)
}
});
键用于其他用途,而不是用于排序。 React 使用 key
s 来优化其内部虚拟 DOM 操作。这意味着你告诉 React "no matter the order of these siblings, the individual sibling is still identified by this key"。这就是 React 知道它是否应该通过重用旧的兄弟姐妹来添加、插入、删除或追加新兄弟姐妹的方式,而不会不必要地丢弃东西。
关于您的排序问题:要更改兄弟姐妹的顺序,只需对 JavaScript 数组 this.props.data
.
进行排序即可
如何在 React 中更改组件项的位置?
除非我误解了,React orders list items by key
,在 DOM 中表示为 data-reactid
,但我不知道如何修改页面上 key
个组件。
即如何抓取组件,更改它的 key
,然后触发渲染,以便重新排序的列表按照您设置的顺序呈现?
例如在下面的代码示例中,当单击 Click me
link 时,第一个列表项将与最后一个列表项交换。
理想情况下,此功能允许您动态 reorder/relocate 页面上的任何组件,而无需更改 render
方法中组件的顺序。
这里是一个 link 到整个项目所在的 repo: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>
)
}
});
key
属性不用于对元素进行排序,而是用于在不同的 render
调用之间协调它。具有相同 key
的元素将不会是 re-rendered 而是相互区分以最佳地更新 DOM。参见 Reconciliation
如果你想重新排序元素,你需要改变它们在你的 JSX 中的位置,或者在你作为 children 在你的 render
方法中传递的元素数组中的位置 (todoNodes
) .
在您的情况下,您可以在 TodoList
组件状态下制作 this.props.data
的副本,然后在 changePosition
方法中使用 this.setState({data: reorderedData})
之类的内容更新该副本.制作该副本的好地方是 getInitialState
.
然后将再次调用 TodoList
的 render
方法,并且您将映射到新重新排序的 this.state.data
以创建有序的 Todo
元素数组随你喜欢。
但是,请注意 props in getInitialState
is an anti-pattern。由于您的数据存在于 TodoBox
组件的状态中,因此避免这种情况的一种方法是让 TodoList
组件在其 changePosition
方法中调用 this.props.onReorder(reorderedData)
。然后,您的 TodoBox
组件可以将事件处理程序传递给它的 TodoList
child,并在调用此处理程序时使用新数据更新其状态。
var TodoBox = React.createClass({
handleReorder: function(reorderedData) {
this.setState({data: reorderedData});
},
render: function(){
return (
<div className="todo-container">
<h4>GAE React Flux Todos</h4>
<TodoList data={this.state.data} onReorder={this.handleReorder} />
</div>
)
}
});
var TodoList = React.createClass({
changePosition: function(e){
// Change position of list item (e.g. to top/certain position/end of list)
// Create a copy of this.props.data and reorder it, then call
// this.props.onReorder to signal to the parent component that
// the data has been reordered
this.props.onReorder(reorderedData);
},
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>
)
}
});
键用于其他用途,而不是用于排序。 React 使用 key
s 来优化其内部虚拟 DOM 操作。这意味着你告诉 React "no matter the order of these siblings, the individual sibling is still identified by this key"。这就是 React 知道它是否应该通过重用旧的兄弟姐妹来添加、插入、删除或追加新兄弟姐妹的方式,而不会不必要地丢弃东西。
关于您的排序问题:要更改兄弟姐妹的顺序,只需对 JavaScript 数组 this.props.data
.