在React中导航离开组件时中止请求

Abort request while navigating away from the component in React

本文关键字:组件 请求 离开 React 导航      更新时间:2023-09-26

我使用react, reduxreact-router。我的页面之一是使API请求并显示数据。它工作得很好。我想知道的是,如果API请求尚未完成,并且用户导航到另一个路由,我希望能够中止请求。

我假设我应该在componentWillUnmount中调度一些操作。只是无法理解它是如何工作的。类似…

componentWillUnmount() {
    this.props.dispatch(Actions.abortRequest());
}

我将把xhr引用存储在动作的某个地方。不确定这是否是正确的方法(我认为不是),有人能指出我在正确的方向吗?

我不认为在行动中存储xhr是正确的。
动作应该是可序列化的,而XMLHttpRequest绝对不是。

相反,我将使用Redux Thunk从我的操作创建者返回一个自定义对象,并执行如下操作:

function fetchPost(id) {
  return dispatch => {
    // Assuming you have a helper to make requests:
    const xhr = makePostRequest(id);
    dispatch({ type: 'FETCH_POST_REQUEST', response, id });
    // Assuming you have a helper to attach event handlers:
    trackXHR(xhr,
      (response) => dispatch({ type: 'FETCH_POST_SUCCESS', response, id }),
      (err) => dispatch({ type: 'FETCH_POST_FAILURE', err, id })
    );
    // Return an object with `abort` function to be used by component
    return { abort: () => xhr.abort() };     
  };
}

现在你可以在你的组件中使用abort:

componentDidMount() {
  this.requests = [];
  this.requests.push(
    this.props.dispatch(fetchPost(this.props.postId))
  );
}
componentWillUnmount() {
  this.requests.forEach(request => request.abort());
}

我不认为这种方法有什么不妥。你在store中持有的是全局应用程序状态;如果你想根据其他动作改变xhr的行为,那么你需要将该状态存储在某个地方。

我见过很多这样的例子:

{
  isFetching: false,
  items: [],
  lastUpdated: null
};

isFetching状态然后用于显示加载旋转器或防止多个xhr请求被发送。我看到你的使用和存储xhr引用,并能够中止它只是一个扩展。