lMount中的异步调用返回尝试设置setState时未定义文档

lMount中的异步调用返回尝试设置setState时未定义文档

本文介绍了从componentWillMount中的异步调用返回尝试设置setState时未定义文档的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的组件的componentWillMount调用中获取数据[实际上是在一个mixin中,但想法相同].在ajax调用返回后,我尝试设置为setState,但是出现错误消息,即未定义文档.

I grab my data in my componentWillMount call of my component [actually it's in a mixin, but same idea]. After the ajax call returns, I attempt to setState, but I get the error that the document is not defined.

我不确定该如何解决.还有什么要等待的吗?一个承诺或回调我应该在其中进行setState?

I'm not sure how to get around this. Is there something to wait for? A promise, or callback I should be doing the setState in?

这就是我想要做的:

componentWillMount: function() {
    request.get(this.fullUrl()).end(function(err, res) {
        this.setState({data: res.body});
    }.bind(this));
}

推荐答案

我以前实际上遇到过类似情况.我认为您遇到的错误是这样的:

I've actually encountered a similar situation before. I assume the error you encountered was something like this:

Uncaught Error: Invariant Violation: replaceState(...): Can only update a mounted or mounting component.

该错误是由以下事实引起的:在React组件中,无法在安装组件之前设置状态.因此,与其尝试在componentWillMount中设置状态,不如在componentDidMount中进行设置.我通常会添加.isMounted()支票,只是为了很好.

The error is caused by the fact that, in React components, you cannot set state before the component is mounted. So, instead of attempting to set the state in componentWillMount, you should do it in componentDidMount. I typically add an .isMounted() check, just for good measure.

尝试这样的事情:

componentDidMount: function () {
  request.get(this.fullUrl()).end(function(err, res) {
    if (this.isMounted()) {
      this.setState({data: res.body});
    }
  }.bind(this));
}


编辑:忘记提及...如果组件在异步操作完成之前被卸载",则您也可能会遇到错误.


Forgot to mention ... If the component gets "unmounted" before the async operation completes, you may also encounter an error.

如果异步操作是可取消的",则可以轻松处理.假设您的上述request()类似于superagent请求(可以取消),我将执行以下操作以避免任何潜在的错误.

This can be easily handled if the async operation is "cancelable". Assuming your request() above is something like a superagent request (which are cancelable), I would do the following to avoid any potential errors.

componentDidMount: function () {
  this.req = request.get(this.fullUrl()).end(function(err, res) {
    if (this.isMounted()) {
      this.setState({data: res.body});
    }
  }.bind(this));
},

componentWillUnmount: function () {
  this.req.abort();
}


编辑#2:在您的评论之一中,您提到了您的意图是创建一个可以异步加载状态的同构解决方案.尽管这超出了原始问题的范围,但我建议您查看反应异步.现成的,它提供了3个工具可以帮助您实现这一目标.


EDIT #2: In one of our comments you mentioned your intent was to create an isomorphic solution that could load state asynchronously. While this is beyond the scope of the original question, I will suggest you check out react-async. Out-of-the-box, it provides 3 tools that can help you achieve this goal.

  1. getInitialStateAsync-通过mixin提供,它允许组件异步获取状态数据.

  1. getInitialStateAsync - this is provided via a mixin, and it allows a component to fetch state data asyncrhonously.

var React = require('react')
var ReactAsync = require('react-async')

var AwesomeComponent = React.createClass({
  mixins: [ReactAsync.Mixin],

  getInitialStateAsync: function(callback) {
    doAsyncStuff('/path/to/async/data', function(data) {
      callback(null, data)
    }.bind(this))
  },

  render: function() {
     ...
  }
});

  • renderToStringAsync()-允许您呈现服务器端

  • renderToStringAsync() - which allows you to render server side

    ReactAsync.renderToStringAsync(
      <AwesomeComponent />,
      function(err, markup, data) {
        res.send(markup);
      })
    );
    

  • injectIntoMarkup()-将注入服务器状态以及标记以确保其在客户端可用

  • injectIntoMarkup() - which will inject the server state, along with the markup to ensure it's available client-side

    ReactAsync.renderToStringAsync(
      <AwesomeComponent />,
      function(err, markup, data) {
        res.send(ReactAsync.injectIntoMarkup(markup, data, ['./app.js']));
      })
    );
    

  • react-async提供的功能远不止于此.您应该查看反应异步文档以获得其功能的完整列表以及我在上面简要介绍过的内容的更全面的解释.

    react-async provides far more functionality than this. You should check out the react-async documentation for a full list of its features, and a more comprehensive explanation of the ones I briefly describe above.

    这篇关于从componentWillMount中的异步调用返回尝试设置setState时未定义文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

    07-24 23:14