我有一个简单的todolist结构到组件的状态。这是一个包含两个名为“content”的字段和一个名为“done”的字段的数组。我通过从父对象传递到TodoItem子项的简单onClick()函数来捕获行项目的点击(如React教程建议):
render() {
const tthis = this;
var myList = tthis.state.todos.map(function(todo,index){
var myOnCLick = function(){
var newTodo = {content: todo.content, done: !todo.done};
tthis.state.todos[index] = newTodo;
tthis.setState({});
}
return <Todo key={index} todo={todo} onClick={myOnCLick}/>
})
return (
<ul className="list">
{ myList }
</ul>
)
}
这段代码没有问题,但我不太喜欢。 我会找到一些很好的解决方案来改变数组中单个项的值。我在React DOC的Immutability helper中找到了:
{$ set:any}完全替换目标。
在这个论坛中,我看到了一个很好的答案:
this.setState({
todos: update(this.state.todos, {1: {done: {$set: true}}})
但我不能在我的情况下使用1。我有索引,它给了我todos列表中点击待办事项的索引。
答案 0 :(得分:1)
您可以按以下方式翻转数组中列出的单个待办事项对象的done
属性的值:
flipDone(id) {
let index = Number(id);
this.setState({
todos: [
...this.state.todos.slice(0, index),
Object.assign({}, this.state.todos[index], {done: !this.state.todos[index].done}),
...this.state.todos.slice(index + 1)
]
});
}
以下是演示:http://codepen.io/PiotrBerebecki/pen/jrdwzB
完整代码:
class TodoList extends React.Component {
constructor() {
super();
this.flipDone = this.flipDone.bind(this);
this.state = {
todos: [
{content: 'Go shopping', done: false},
{content: 'Walk the dog', done: false},
{content: 'Wash the dishes', done: false},
{content: 'Learn React', done: false}
]
};
}
flipDone(id) {
let index = Number(id);
this.setState({
todos: [
...this.state.todos.slice(0, index),
Object.assign({}, this.state.todos[index], {done: !this.state.todos[index].done}),
...this.state.todos.slice(index + 1)
]
});
}
render() {
const myList = this.state.todos.map((todo, index) => {
return (
<Todo key={index}
clickHandler={this.flipDone}
content={todo.content}
done={todo.done}
id={index}
/>
);
})
return (
<ul className="list">
{myList}
</ul>
);
}
}
class Todo extends React.Component {
constructor() {
super();
this.handleClick = this.handleClick.bind(this);
}
handleClick(event) {
this.props.clickHandler(event.target.id);
}
render() {
return (
<li>
<button onClick={this.handleClick}
id={this.props.id}>
Click me
</button> ---
{String(this.props.done)} ---
{this.props.content}
</li>
);
}
}
ReactDOM.render(
<TodoList />,
document.getElementById('app')
);