我正在使用jsonplaceholder来模拟我的数据请求,但是我通过复选框遇到了受控组件的一些问题。困扰我的两种方法是uncompleteTask()/ completeTask(),因为当我尝试单击复选框时,它会完全抹掉整个帖子列表。
我的目标是能够根据完整/ id /标题进行排序,并选中/取消选中每个任务。任何帮助将不胜感激。...
import React, { Component } from "react";
const restfulAPI = "https://jsonplaceholder.typicode.com/todos";
class App extends Component {
constructor(props) {
super(props)
this.state = { filter: "id", tasks: []};
}
componentDidMount() {
fetch(`${restfulAPI}`)
.then(response => response.json())
.then(tasks => this.setState({ tasks }));
}
uncompleteTask = id => {
fetch(`${restfulAPI}/${id}`, {
method: "PATCH",
body: JSON.stringify({
completed: false
}),
headers: {
"Content-type": "application/json; charset=UTF-8"
}
})
.then(response => response.json())
.then(json => {
let newTasks = [];
for (let i = 0; i < this.state.tasks.length; i++) {
newTasks = newTasks.concat(
json.id === this.state.tasks[i].id
? { ...this.state.tasks[i], completed: false }
: this.state.tasks[i]
);
}
this.setState({
tasks: newTasks
});
});
};
completeTask = id => {
fetch(`${restfulAPI}/${id}`, {
method: "PATCH",
body: JSON.stringify({
completed: true
}),
headers: {
"Content-type": "application/json; charset=UTF-8"
}
})
.then(response => response.json())
.then(json => {
let newTasks = [];
for (let i = 0; i < this.state.tasks.length; i++) {
newTasks = newTasks.concat(
json.id === this.state.tasks[i].id
? { ...this.state.tasks[i], completed: true }
: this.state.tasks[i]
);
}
this.setState({
tasks: newTasks
});
});
};
getSortedTasks = () => {
return this.state.tasks.sort((a, b) => {
if (this.state.filter === "id") {
return a.id > b.id ? 1 : -1;
}
if (this.state.filter === "completed") {
return a.completed ? -1 : 1;
}
if (this.state.filter === "title") return a.title > b.title ? 1: -1;
});
};
setFilterCompleted = () => {
this.setState({ filter: "completed" });
}
setFilterId = () => {
this.setState({ filter: "id" });
}
setFilterTitle = () => {
this.setState({ filter: "title" });
}
addTask = () => {
const task = document.getElementById("newTask").value;
fetch("https://jsonplaceholder.typicode.com/todos", {
method: "POST",
body: JSON.stringify({
title: task,
userId: 1,
completed: false
}),
headers: {
"Content-type": "application/json; charset=UTF-8"
}
})
.then(response => response.json())
.then(json => this.setState({ tasks: this.state.tasks.concat({ ...json, id: this.state.tasks.length + 1 }) }));
};
render() {
const tasks = this.getSortedTasks();
return (
<div className="main">
<div>
Add Task: <input id="newTask" />
<button onClick={this.addTask}>Add</button>
</div>
<table>
<thead>
<tr>
<th onClick={this.setFilterCompleted}>✓</th>
<th onClick={this.setFilterId}>ID</th>
<th onClick={this.setFilterTitle}>Task</th>
</tr>
</thead>
<tbody>
{tasks.map(task => (
<tr key={task.id}>
<td>
{task.completed ? (
<input
onChange={this.uncompleteTask}
checked
type="checkbox"
/>
) : (
<input type="checkbox" onChange={this.completeTask} />
)}
</td>
<td>{task.id}</td>
<td className="strikethrough">{task.title}</td>
</tr>
))}
</tbody>
</table>
</div>
);
}
}
export default App;
答案 0 :(得分:1)
因为concat
不修改newTasks
,它返回的结果将是两个数组的串联。
您的newTasks
始终是一个空数组
尝试一下:
let newTasks = [];
for (let i = 0; i < this.state.tasks.length; i++) {
newTasks = newTasks.concat(
json.id === this.state.tasks[i].id
? { ...this.state.tasks[i], completed: false }
: this.state.tasks[i]
);
}
this.setState({
tasks: newTasks
});
只是为了使其更清晰
let a = [1];
let b = [2,3];
let result = a.concat(b);
// a = [1]; b = [2,3]; result = [1,2,3];
详细了解此here。