【问题标题】:Why do I have to refresh page manually after delete?为什么删除后必须手动刷新页面?
【发布时间】:2019-03-24 13:05:53
【问题描述】:

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

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

【问题讨论】:

  • 您是否正在重新获取主页中componentDidMount 上的项目?
  • 不,我将在详细视图页面上删除它们并重定向到主页。
  • 您首先需要展示如何获取和设置数据。

标签: reactjs


【解决方案1】:

你在渲染中看到的就是你在你的状态下所拥有的。

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


所以你有两种方法。

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

  2. fire delete 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>
    );
  }

}

【讨论】:

  • 如果我的数据在 CircuitList vs. App 中会有什么变化吗?
  • CircuitDetail 在 App 还是 CircuitList 中?
  • 无论如何,您可以在设计保存状态/数据的位置时使用此原则....“数据总是向下传递,事件总是向上传递”。因此,在将数据向下传递到 CircuitDetail 之前向上传递数据(CircuitList => App)是一种反模式。这就是为什么在 中存储数据从反应的角度来看是有意义的。
  • 感谢您的提示!我重新组织了我的应用程序并删除了它,但它没有重定向到主页。我需要添加`this.history.push('/')吗?
  • 由于某种原因,当我添加 this.props.history.push('/'); 它不再删除 并且 它不会重定向。
【解决方案2】:

您需要从状态中删除元素(如果这是在反应状态,则从反应状态中删除。如果它处于 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();
}

【讨论】:

  • 我明白了,如果我使用第一个示例,这应该是为了操纵主页上的状态,所以常量和名称应该相同?
  • 显然不是,但是你需要向这个组件发送一些回调。这样您就可以告诉主页有关删除了哪个电路ID
  • array.indexOf 中的数组是否应该引用代码中的新数组电路?另外——这会删除对象,但只有在我删除 this.forceUpdate(); 时才会重定向,但当我包含 forceUpdate 时,它​​不会删除。
  • 如果您要更改路线,则无需执行forceUpdatearray.indexOf在数组中找到你要删除的circuitId的索引
【解决方案3】:

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

类似这样的:

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

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

【讨论】:

    【解决方案4】:

    如果您使用redux Store管理CircuitList中的项目,一个可能的原因是即使通过api调用删除了Entry,数据仍然保留在redux store中,需要刷新一旦条目被删除。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-19
      • 2017-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-03
      • 2016-11-17
      • 1970-01-01
      相关资源
      最近更新 更多