为什么删除后必须手动刷新页面?
当我删除一个电路(通过详细信息页面上的链接)并重定向回主页时,我删除的对象仍然存在,直到我手动刷新页面。
我曾尝试通过路由器传入
props
:
<Route exact path='/' render={(props) => <CircuitList {...props} /> } />
我曾尝试将删除功能从详细信息视图容器移动到列表视图容器,但无法弄清楚如何通过组件向下传递该功能。
删除操作
handleDeleteCircuit = (event) => {
const circuitID = this.props.match.params.id;
axios.delete(`link-to-api`, this.state);
this.props.history.push('/');
this.forceUpdate();
}
每次我删除一个电路时,它都会从 api 中删除,但是当它重定向到主页时,它仍然存在,直到我手动刷新页面。
您在渲染中看到的就是您在状态下拥有的内容。
TL;DR 您需要更新您的状态。
因此您有两种方法。
-
乐观更新,向服务器触发删除 api + setState 以删除您状态下的数据。并在您收到删除 api 的响应后采取相应措施。
-
触发删除 api 后,再次从服务器重新获取整个数据并更新状态。
我建议使用选项 1,因为用户感觉它更快。
这里有一些额外的概念。
-
如果您想与您的“CircuitList”和“CircuitDetail”页面共享状态(数据)。您应该将电路存储在某个父级中,例如 App(或 Redux 状态),然后将它们传递给每个组件。
-
再次,乐观更新模式。立即触发 API + setState...如果出现问题则恢复。
如果您需要更多帮助,请告诉我 :)
以下是您可以做的事情。
// assuming you have your data in App, state.circuits
class App extends React.Component {
state = {
circuits: [
{ id: 1, title: 'Circuit 1' },
{ id: 2, title: 'Circuit 2' },
{ id: 3, title: 'Circuit 3' },
],
}
afterDeleteCircuit = (circuitID) => {
// state, before delete anything
const currentCircuits = this.state.circuits;
// Remove deleted item from state.
this.setState({
circuits: currentCircuits.filter(circuit => circuit.id !== circuitID),
});
// Fire delete API
axios
.delete(`link-to-api`, this.state)
.then(response => {
if (response.status === 'error') {
// Oops, something went wrong. Let's get that deleted Id back.
this.setState({
circuits: currentCircuits,
});
// Show Error message here.
} else {
// Delete successfully, do nothing.
// Because we already remove the deleted id from state.
// Show success message here.
}
});
}
render() {
return (
<Router>
<Route exact path='/' render={(props) => <CircuitList {...props} circuits={this.state.circuits} /> } />
<Route path='/circuits/:id' render={(props) => <CircuitDetail {...props} onDelete={this.afterDeleteCircuit} /> } />
</Router>
);
}
}
class CircuitList extends React.Component {
render () {
const { circuits } = this.props;
return (
<div>
{circuits.map(circuit => (
<li>{circuit.title} <Link to={`/circuit/${circuit.id}`}>Edit</Link></li>
)}
</div>
);
}
}
class CircuitDetail extends React.Component {
handleDelete = (e) => {
const { match, history } = this.props;
const id = match.params.id;
this.props.onDelete(id);
history.push('/');
}
render () {
return (
<div>
...
// Delete button
<button onClick={this.handleDelete}>Delete</button>
</div>
);
}
}
您需要从状态中删除元素(如果处于 react 状态,则从 react 状态中删除。如果处于 redux 状态,则从 redux 状态中删除元素)
或者您可以在 index 路由再次挂载时(在 componentDidMount 中)从后端再次获取所有项目,但由于网络调用比状态操作更重。我会采取乐观的方法从状态中删除项目(无论是 react 还是 redux 或您正在使用的任何其他状态管理库)
handleDeleteCircuit = async (event) => {
const circuitID = this.props.match.params.id;
await axios.delete(`link-to-api`, this.state);
const circuits = [...this.state.circuits];
const index = array.indexOf(circuitID)
//or remove element from the redux state
if (index !== -1) {
circuits.splice(index, 1);
this.setState({circuits});
}
this.props.history.push('/');
this.forceUpdate();
}
您没有任何从电路列表中删除电路的代码。
像这样:
let this.state.circuits = this.state.circuits.filter((circuit) => {
return circuit.id == circuitId
})
我不熟悉 React,所以可能需要进行一些更改。