学习ReactJs,我将使用最佳实践来实现这一点。请任何人添加其他功能或对您的解决方案发表评论。
我试图通过单击一组向上/向下按钮来构建重新排序列表项组件。
1)我如何显示所有道具组件值及其bgColor?
2)为了处理事件,我必须使用构造函数并在内部添加onClickUp()和onClickDown()方法?
FruitList组件:
class FruitList extends Component {
constructor(props) {
super(props);
this.state = { // set new state for bind key items
items : [
{'id': 1, 'name': 'orange', 'bgColor': '#f9cb9c'},
{'id': 2, 'name': 'lemon','bgColor' : '#fee599'},
{'id': 3, 'name': 'strawberry', 'bgColor': '#e06666'},
{'id': 4, 'name': 'apple', 'bgColor' : '#b6d7a7'}
]
}
}
onMoveUp = (key) => {
if(key === 0) return; // disable method when the key its equal to 0
const { items } = this.props; // assign props to items for don't repeat my self
const index = key - 1; // save in memory index value less than one
const itemAbove = items[index]; // save in memory items index
items[key - 1] = items[key]; // match id value with the key object
items[key] = itemAbove;
this.setState({ items }); // set new state
}
onMoveDown = (key) => {
const { items } = this.props;
if(key === items.length - 1) return;
const index = key + 1;
const itemBelow = items[index];
items[key + 1] = items[key];
items[key] = itemBelow;
this.setState({ items });
}
render() {
const { items } = this.state;
return (
<ul>
{items.map((item, key) =>
<li key={key} style={{ backgroundColor: item.bgColor }}>
<div className="fruitsId">{ key + 1 }</div>
<div className="fruitsName">{ item.name }</div>
<div className="fruitsArrows">
<span onClick={() => this.onMoveUp(key)}>▲</span>
<span onClick={() => this.onMoveDown(key)}>▼</span>
</div>
</li>
)}
</ul>
);
}
}
App.js组件:
class App extends Component {
constructor(props) {
super(props);
this.state = {
fruitList : [
{'id': 1, 'name': 'orange', 'bgColor': '#f9cb9c'},
{'id': 2, 'name': 'lemon','bgColor' : '#fee599'},
{'id': 3, 'name': 'strawberry', 'bgColor': '#e06666'},
{'id': 4, 'name': 'apple', 'bgColor' : '#b6d7a7'}
]
}
}
render() {
return (
<FruitList items={this.state.fruitList} />
);
}
}
ReactDOM.render(<App />, document.body);
答案 0 :(得分:0)
是的,您应该lift the sate up并提供回调onMoveUp/onMoveDown
并将其传递给FruitList
,或者您可以拥有一个onMove(id: number, direction: number)
并传递+1
(枚举DOWN )或-1
(向上枚举)向右移动。请参见下面的代码。
如果需要,可以将下面代码中的方法handleMove
移到FruitList
类中,并命名为handleListChanged
这样,App
仅在每个时间改变了。我猜我的代码对您来说更好,因为您是从React开始的。
const UP = -1
const DOWN = 1
class FruitList extends React.Component {
render() {
const {fruitList, onMove} = this.props
return (
<ul>
{fruitList.map((item) =>
<li key={item.id} style={{ backgroundColor: item.bgColor }}>
<div className="fruitsId">{item.id}</div>
<div className="fruitsName">{item.name}</div>
<div className="fruitsArrows">
<a onClick={() => onMove(item.id, UP)}>▲</a>
<a onClick={() => onMove(item.id, DOWN)}>▼</a>
</div>
</li>
)}
</ul>
);
}
}
class App extends React.Component {
state = { // set new state for bind key items
items: [
{'id': 1, 'name': 'orange', 'bgColor': '#f9cb9c'},
{'id': 2, 'name': 'lemon','bgColor' : '#fee599'},
{'id': 3, 'name': 'strawberry', 'bgColor': '#e06666'},
{'id': 4, 'name': 'apple', 'bgColor' : '#b6d7a7'},
]
}
handleMove = (id, direction) => {
const {items} = this.state
const position = items.findIndex((i) => i.id === id)
if (position < 0) {
throw new Error("Given item not found.")
} else if (direction === UP && position === 0 || direction === DOWN && position === items.length - 1) {
return // canot move outside of array
}
const item = items[position] // save item for later
const newItems = items.filter((i) => i.id !== id) // remove item from array
newItems.splice(position + direction, 0, item)
this.setState({items: newItems})
}
render() {
return (
<FruitList fruitList={this.state.items} onMove={this.handleMove} />
)
}
}
ReactDOM.render(
<App />,
document.body
);
/* Add your css styles here */
body {
font-family: Arial, Helvetica, sans-serif;
}
ul {
list-style: none;
padding: 0;
}
li {
margin: 0 auto;
text-align: center;
width: 400px;
display: flex;
align-items: center;
justify-content: center;
}
li div {
border: 1px solid white;
padding: 5px 0;
}
.fruitsId,
.fruitsArrows {
width: 50px;
}
.fruitsName {
width: 300px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
答案 1 :(得分:0)
您遇到了几个问题。首先,您需要映射水果清单中各项的属性,并且bgColor的变量必须一致。请参阅下面的功能示例,至少可以开始使用功能正常的组件:
class FruitsList extends React.Component {
render() {
return (
<ul>
{this.props.items.map((item, key) =>
<li style={{ backgroundColor: item.bgColor }}>
<div className="fruitsId">{ item.id }</div>
<div className="fruitsName">{ item.name }</div>
<div className="fruitsArrows">
<span>▲</span>
<span>▼</span>
</div>
</li>
)}
</ul>
);
}
}
FruitsList.defaultsProps = {Items:[]}
class App extends React.Component {
state = {
fruitsList : [
{ 'id': 1, 'name': 'orange', 'bgColor': '#f9cb9c'},
{ 'id': 2, 'name': 'lemon','bgColor' : '#fee599'},
{ 'id': 3, 'name': 'strawberry', 'bgColor': '#e06666'},
{ 'id': 4, 'name': 'apple', 'bgColor' : '#b6d7a7'}
]
}
render() {
return (
<FruitsList items={this.state.fruitsList} />
);
}
}
ReactDOM.render(
<App />,
document.body
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>