我一直在网上跟踪MERN堆栈教程之一(制作一个简单的todo应用程序),因此决定不按脚本进行操作。我想添加一个按钮以删除特定项目。删除功能运行良好,但是它要求用户单击删除按钮后手动刷新页面,以便查看数据库(MongoDB)中新的元素列表。我希望页面在单击事件后自动刷新,但是我不确定从哪里开始。在react渲染器中有一个表,该表引用一个变量以实际组装表的组件-这是存在删除按钮的地方。这是我的代码:
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import axios from 'axios';
const Todo = props => (
<tr>
<td className={props.todo.todo_completed ? 'completed' : ''}>{props.todo.todo_title}</td>
<td className={props.todo.todo_completed ? 'completed' : ''}>{props.todo.todo_description}</td>
<td className={props.todo.todo_completed ? 'completed' : ''}>{props.todo.todo_responsible}</td>
<td className={props.todo.todo_completed ? 'completed' : ''}>{props.todo.todo_priority}</td>
<td>
<Link to={"/edit/"+props.todo._id}>Edit</Link>
</td>
<td>
{/* this is where the delete happens */}
<button onClick={ () =>
axios.delete('http://localhost:4000/todos/'+props.todo._id)
.then(console.log("Deleted: " + props.todo._id))
.catch(err => console.log(err))
}
>Delete</button>
</td>
</tr>
)
export default class TodosList extends Component {
constructor(props) {
super(props);
this.state = {todos: []};
}
componentDidMount() {
axios.get('http://localhost:4000/todos/')
.then(res => {
this.setState({ todos: res.data });
})
.catch(function(err){
console.log(err);
})
}
todoList() {
return this.state.todos.map(function(currentTodo, i){
return <Todo todo={currentTodo} key={i} />;
})
}
render() {
return (
<div>
<h3>Todos List</h3>
<table className="table table-striped" style={{ marginTop: 20 }} >
<thead>
<tr>
<th>Title</th>
<th>Description</th>
<th>Responsible</th>
<th>Priority</th>
<th>Action</th>
<th>Remove Item</th>
</tr>
</thead>
<tbody>
{ this.todoList() }
</tbody>
</table>
</div>
)
}
}
希望在这里的人可以指引我正确的方向。
谢谢
答案 0 :(得分:2)
从TodosList
组件中成功删除特定项目后,您可以从Todo
组件状态中删除特定项目。为此,您可以
1)在TodosList
组件中添加一个方法。
deleteItemHandler = (id) => {
const updatedTodos = this.state.todos.filter(todo => todo.id !== id);
this.setState({todos: updatedTodos})
}
2)将方法deleteItemHandler
作为道具传递给Todo
组件
todoList() {
return this.state.todos.map((currentTodo, i) => {
return <Todo todo={currentTodo} deleteItem={this.deleteItemHandler} key={i} />;
})
}
3)成功删除项目后使用它
<td>
{/* this is where the delete happens */}
<button onClick={ () =>
axios.delete('http://localhost:4000/todos/'+props.todo._id)
.then(() => props.deleteItem(props.todo._id))
.catch(err => console.log(err))
}
>Delete</button>
</td>
另一种方式
代替从TodosList
组件中删除项目,您还可以更新状态。为此,您可以
1)添加在TodosList
组件中更新的方法
updateStateHandler = () => {
axios.get('http://localhost:4000/todos/')
.then(res => {
this.setState({ todos: res.data });
})
.catch(function(err){
console.log(err);
})
}
2)将方法updateStateHandler
作为道具传递给Todo
组件
todoList() {
return this.state.todos.map((currentTodo, i) => {
return <Todo todo={currentTodo} updateState={this.updateStateHandler} key={i} />;
})
}
3)成功删除项目后使用它
<td>
{/* this is where the delete happens */}
<button onClick={ () =>
axios.delete('http://localhost:4000/todos/'+props.todo._id)
.then(() => props.updateState())
.catch(err => console.log(err))
}
>Delete</button>
</td>
答案 1 :(得分:1)
您需要执行此操作
export default class TodosList extends Component {
constructor(props) {
super(props);
this.state = {todos: []};
this.fetchTodos = this.fetchTodos.bind(this);
}
fetchTodos() {
axios.get('http://localhost:4000/todos/')
.then(res => {
this.setState({ todos: res.data });
})
.catch(function(err){
console.log(err);
});
}
componentDidMount() {
this.fetchTodos();
}
todoList() {
return this.state.todos.map((currentTodo, i) => {
return <Todo todo={currentTodo} fetchTodos={this.fetchTodos} key={i} />;
})
}
...
Todo:
<td>
{/* this is where the delete happens */}
<button onClick={ () =>
axios.delete('http://localhost:4000/todos/'+props.todo._id)
.then(() => {
console.log("Deleted: " + props.todo._id);
props.fetchTodos();
})
.catch(err => console.log(err));
}
>Delete</button>
</td>
答案 2 :(得分:0)
呈现表的权限是您的TodosList
类,因此需要告知它进行删除:
class TodosList extends ... {
...
todoList() {
return this.state.todos.map((currentTodo, i) => {
let onDelete = () => {
this.removeItem(i);
};
// NEVER use an array position as key. The key is meant to uniquely
// identify the _item itself_ and is used in DOM diffing. Moving elements
// inside an array does not change those elements in the slightest and only
// requires moving DOM nodes around, but if you use array position as key,
// what you've now done is said that _everything in the DOM node has changed_
// So: don't do that. Use a real, item based, value.
return <Todo todo={currentTodo} key={currentTodo.id} onDelete={onDelete}/>;
// Of course this assumes todo items have an `id` property.
// If they don't, pick another property _on the todo item_ that
// uniquely identifies it.
});
}
removeItem(i) {
let todos = this.state.todos;
todos.splice(i,1);
// This single call now results in all the UI updates that you
// need to have happen: the todo item is no longer in the state,
// and so its DOM node will be removed from the page. And because
// we're now using real keys, React will not touch any of the other
// DOM nodes. The UI update is near-instant.
this.setState({ todos });
}
...
}
然后,一旦删除发生,各个按钮便可以调用它们自己的onDelete:
const deleteThisItem = () => {
axios
.delete('http://localhost:4000/todos/'+props.todo._id)
.then(this.props.onDelete())
.catch(err => console.log(err))
};
<button onClick={deleteThisItem}>delete</button>
所以流程是:
setState
,React就会呈现需要呈现的内容。