当我调用createTodo
函数时,this.state.todos
被添加到新的待办事项中。具有time
属性的对象想要移动到对象times
中的select
数组,但是times
被加倍。
我认为应该归咎于.slice方法并复制数组。如何解决呢?
Todo
class Todo extends Component {
render() {
return (
<li>
<div>
{this.props.todo.description}
</div>
</li>
)
}
}
应用
class App extends React.Component {
constructor() {
super();
this.state = {
todos: [
{
time: '00:00:10',
description: 'Hello'
},
{
time: '00:00:20',
description: 'World'
}
],
todo: {
'time': '00:00:30',
'description': 'W'
},
select: {
"times": [{ 'time': '00:00:40' }, { 'time': '00:00:50' }],
"description": " ytytyty",
"id": 3,
"title": "gfgfgfgfgf"
}
};
}
addTodo = (todo) => {
const news = this.state.todos.slice();
news.push(this.state.todo);
this.setState({ todos: news });
};
render() {
this.state.todos.forEach(t => {
if (t.time) this.state.select.times.push({
time: t.time
})
});
console.log(this.state.todos);
console.log(this.state.select);
return (
<div>
<ul>
{
this.state.todos
.map((todo, index) =>
<Todo
key={index}
index={index}
todo={todo}
/>
)
}
</ul>
<button onClick={this.createTodo}>button</button>
</div>
);
}
console.log(this.state.select) -> return-->
times: [
{time: "00:00:40"}
{time: "00:00:50"}
{time: "00:00:10"} //repeat
{time: "00:00:20"} //repeat
{time: "00:00:10"}
{time: "00:00:20"}
{time: "00:00:30"}
title: "gfgfgfgfgf"
]
期待效果:
times: [
{time: "00:00:40"}
{time: "00:00:50"}
{time: "00:00:10"}
{time: "00:00:20"}
{time: "00:00:30"}
title: "gfgfgfgfgf"
]
演示 https://stackblitz.com/edit/react-jfkwnu
加载组件后,它应为:selectTodo: {"times": [{'time': '00: 00: 40 '}, {' time ':' 00: 00: 50 '}], "description": "ytytyty", "id": 3, "title": "gfgfgfgfgf"}
首次点击按钮:-> selectTodo: {times: [{time: "00:00:40"} {time: "00:00:50"} {time: "00:00:10"} {time: " 00:00:20 "} {time:" 00:00:30 "} title:" gfgfgfgfgf "]," description ":" ytytyty "," id ": 3," title ":" gfgfgfgfgf "}
第二次点击按钮更改-> selectTodo: {times: [{time: "00:00:40"} {time: "00:00:50"} {time: "00:00:10"} {time: "00 : 00: 20 "} {'time': '00: 00: 30'}, {time:" 00:00:30 "} title:" gfgfgfgfgf "]" description ":" ytytyty "," id ": 3 , "title": "gfgfgfgfgf"}
答案 0 :(得分:2)
据我了解,您想独立维护todos
和selectTodo
,但始终将所有todos
次镜像到selectTodo.times
。
总结:
todos
将镜像到selectTodo.times
todos
和selectTodo.times
。要知道用户是否已经使用过createTodo
方法,我刚刚将withInitialTodos
添加到了该状态。它不是很干净,但是可以满足您的需要。
请注意,正如Bergi在上面的评论中所述,您应该避免在render
方法中更新状态。
constructor() {
super();
this.state = {
withInitialTodos: true,
todos: [
{
time: '00:00:10',
description: 'Hello'
},
{
time: '00:00:20',
description: 'World'
}
],
todo: {
'time': '00:00:30',
'description': 'W'
},
selectTodo: {
"times": [{ 'time': '00:00:40' }, { 'time': '00:00:50' }],
"description": " ytytyty",
"id": 3,
"title": "gfgfgfgfgf"
}
};
}
createTodo = (todo) => {
this.setState({
withInitialTodos: false,
todos: [].concat(this.state.todos, this.state.todo),
selectTodo: {
...this.state.selectTodo,
times: [].concat(
this.state.selectTodo.times,
this.state.withInitialTodos ? this.state.todos.map(({ time }) => ({ time })): [],
{
time: this.state.todo.time
}
)
}
});
}
render() {
console.log(this.state.todos);
console.log(this.state.selectTodo.times);
return (
<div>
<ul>
{this.state.todos.map((todo, index) => (
<Todo
key={index}
index={index}
todo={todo}
/>
)}
</ul>
<button onClick={this.createTodo}></button>
</div>
);
}