javascript React.js:如何更改组件项的位置
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29020771/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
React.js: How do you change the position of a Component item
提问by Ben
How do you change the position of a Component item in React?
你如何改变 React 中组件项的位置?
Unless I've misunderstood it, React orders list items by key
, which is represented in the DOM by data-reactid
, but I don't know how to modify the key
of components on the page.
除非我理解错了,React 将列表项按 by 排序key
,在 DOM 中表示为 by data-reactid
,但我不知道如何修改key
页面上的组件。
i.e. How do you grab the component, change it's key
, and then fire a render so that the reordered list renders in the order you've set?
即您如何获取组件,更改它key
,然后触发渲染,以便重新排序的列表按照您设置的顺序进行渲染?
e.g. in the following code example, when the Click me
link is clicked, the first list item would be swapped with the last list item.
例如,在下面的代码示例中,当Click me
单击链接时,第一个列表项将与最后一个列表项交换。
Ideally, this functionality would allow you to dynamically reorder/relocate any component on the page without changing the order of components in the render
method.
理想情况下,此功能将允许您动态重新排序/重新定位页面上的任何组件,而无需更改render
方法中组件的顺序。
Here is a link to the repo where the full project is located: https://github.com/bengrunfeld/gae-react-flux-todos
这是完整项目所在的 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>
)
}
});
回答by Alexandre Kirszenberg
The key
prop is not used to order the element, but to reconciliate it between different render
calls. Elements with the same key
will not be re-rendered but rather diffed against each other in order to update the DOM optimally. See Reconciliation
该key
道具不用于排序元素,但不同之间reconciliate它render
调用。具有相同元素的元素key
不会被重新渲染,而是会相互区分,以便以最佳方式更新 DOM。见对帐
If you want to reorder elements, you need to change their position in your JSX or in the element array you pass as children in your render
method (todoNodes
).
如果要对元素重新排序,则需要更改它们在 JSX 或在render
方法 ( todoNodes
) 中作为子项传递的元素数组中的位置。
In your case, you could make a copy of this.props.data
in the TodoList
component state, then update that copy in your changePosition
method with something like this.setState({data: reorderedData})
. A good place to make that copy would be in getInitialState
.
在您的情况下,您可以this.props.data
在TodoList
组件状态中创建一个副本,然后在您的changePosition
方法中使用类似this.setState({data: reorderedData})
. 制作该副本的好地方是getInitialState
.
The render
method of your TodoList
would then be called again, and you would map over your newly reordered this.state.data
to create an array of Todo
elements ordered to your liking.
然后将再次调用render
您的方法,您TodoList
将映射新重新排序this.state.data
的Todo
元素以创建一个按您的喜好排序的元素数组。
However, be aware that props in getInitialState
is an anti-pattern. Since your data lives in the state of your TodoBox
component, a way to avoid this would be to have your TodoList
component call this.props.onReorder(reorderedData)
in its changePosition
method. Your TodoBox
component could then pass an event handler to its TodoList
child, and update its state with the new data whenever this handler is called.
但是,请注意props ingetInitialState
是一种反模式。由于您的数据存在于TodoBox
组件的状态中,因此避免这种情况的一种方法是让您的TodoList
组件this.props.onReorder(reorderedData)
在其changePosition
方法中调用。TodoBox
然后,您的组件可以将事件处理程序传递给其TodoList
子级,并在调用此处理程序时使用新数据更新其状态。
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>
)
}
});
回答by Rygu
Keys are used for something else, not for sorting. React uses key
s to optimize its internal Virtual DOM operations. It means you tell React that "no matter the order of these siblings, the individual sibling is still identified by this key". That's how React knows whether it should prepend, insert, delete, or append new siblings by reusing the old, without throwing stuff away unnecessarily.
键用于其他用途,而不是用于排序。React 使用key
s 来优化其内部的 Virtual DOM 操作。这意味着你告诉 React “无论这些兄弟姐妹的顺序如何,单个兄弟姐妹仍然由这个键标识”。这就是 React 如何知道它是否应该通过重用旧的来添加、插入、删除或附加新的兄弟姐妹,而不会不必要地扔掉东西。
As for your sorting question: To change the order of the siblings, just sort the JavaScript array this.props.data
.
至于您的排序问题:要更改兄弟姐妹的顺序,只需对 JavaScript 数组进行排序即可this.props.data
。