它是否被认为是 React Component 中的反模式解决Promise?

IT技术 reactjs redux
2021-05-11 12:46:46

在应用程序的许多地方,我们确实调用了一个/searchapi,您可以从中选择结果的 id,然后结果将被丢弃,由于结果是暂时使用的,这让我觉得不值得保存它们,甚至不值得调度操作(除了设置 isLoading 标志)。但它会迫使我解决react组件中的Promise,这被认为是不好的做法还是反模式?

例如:

componentDidMount() {
    this.props.doSearch(criterias)
      .then(res => this.setState({ results: res.results }) )
  }
2个回答

是的,这是 ReactJS 中已知的反模式,因为您不能保证在 promise 解析时组件仍然存在。您可以使用 this.isMounted 在技术上进行检查,但这也被认为是一种反模式。

问题是 ReactJS 并没有真正设计成一个完整的应用程序框架 - 当它实际上只是一个 V 时,你有点将 MVC 推入其中。为了最有效,React 应该与其他一些库(Redux非常流行)可以存储应用数据,然后React可以为您呈现。最好将 React 视为将内部 UI 状态转换为实际 UI 的库。这不利于管理状态。

https://facebook.github.io/react/blog/2015/12/16/ismounted-antipattern.html

是的,这是 React 中的一种反模式。可能this.setState({ results: res.results })会在组件卸载后执行。

最好的方法是将状态(搜索挂起/搜索已解决)移出react组件。您可以利用redux+redux-thunkmobxflux来帮助您。对于简单的情况,您可以构建可取消的Promise。

const makeCancelable = (promise) => {
  let hasCanceled_ = false;

  const wrappedPromise = new Promise((resolve, reject) => {
    promise.then(
      val => hasCanceled_ ? reject({isCanceled: true}) : resolve(val),
      error => hasCanceled_ ? reject({isCanceled: true}) : reject(error)
    );
  });

  return {
    promise: wrappedPromise,
    cancel() {
      hasCanceled_ = true;
    },
  };
};

class MyComponent extends Component {
  componentDidMount() {
    this.cancellableSearch = makeCancelable(this.props.doSearch());
    this.cancellableSearch.then((res) => {
      this.setState({ results: res.results });
    }).catch((reason) => {
      if (!isCanceled.isCanceled) {
        console.error('some error occurs', reason);
      }
    })
  }

  componentWillUnmount() {
    this.cancellableSearch.cancel();
  }

  // ...
}

可取消的Promise代码从这里复制:https : //facebook.github.io/react/blog/2015/12/16/ismounted-antipattern.html