在React Component中它被认为是反模式解决的承诺吗?

时间:2017-08-30 23:38:06

标签: reactjs redux

在应用程序的许多地方我们都会调用/search api,你从结果中选择id然后结果将被丢弃,因为结果是暂时使用的,这让我觉得它和#39;不值得保存它们甚至不值得发送动作(除了设置isLoading标志)。但它会迫使我解决反应组件中的承诺,它被认为是不良做法还是反模式?

例如:

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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

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

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

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();
  }

  // ...
}

可以从此处复制可取消的承诺代码:https://facebook.github.io/react/blog/2015/12/16/ismounted-antipattern.html