开发者问题收集

为什么删除后必须手动刷新页面?

2019-03-24
24663

当我删除一个电路(通过详细信息页面上的链接)并重定向回主页时,我删除的对象仍然存在,直到我手动刷新页面。

我曾尝试通过路由器传入 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 中删除,但是当它重定向到主页时,它仍然存在,直到我手动刷新页面。

3个回答

您在渲染中看到的就是您在状态下拥有的内容。

TL;DR 您需要更新您的状态。


因此您有两种方法。

  1. 乐观更新,向服务器触发删除 api + setState 以删除您状态下的数据。并在您收到删除 api 的响应后采取相应措施。

  2. 触发删除 api 后,再次从服务器重新获取整个数据并更新状态。

我建议使用选项 1,因为用户感觉它更快。


这里有一些额外的概念。

  1. 如果您想与您的“CircuitList”和“CircuitDetail”页面共享状态(数据)。您应该将电路存储在某个父级中,例如 App(或 Redux 状态),然后将它们传递给每个组件。

  2. 再次,乐观更新模式。立即触发 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>
    );
  }

}
Doppio
2019-03-24

您需要从状态中删除元素(如果处于 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();
}
Ajay Gaur
2019-03-24

您没有任何从电路列表中删除电路的代码。

像这样:

let this.state.circuits = this.state.circuits.filter((circuit) => {
    return circuit.id == circuitId
})

我不熟悉 React,所以可能需要进行一些更改。

SimonDepelchin
2019-03-24