【问题标题】:Error when updating ReactJS state with complex object使用复杂对象更新 ReactJS 状态时出错
【发布时间】:2016-05-04 13:39:48
【问题描述】:

当我做类似的事情时:

getInitialState: function() {
  return { previews: [], isLoading: true, error: "", nextCursor: "" };
},
componentDidMount: function(){
  $.ajax("/my-url", {
    method: "GET",
    success: this.previewsReceived,
    failure: this.previewsFailedToReceive
  });
},
previewsReceived: function(previews){
  var tmpState =  { isLoading: false, previews: previews.data, nextCursor: previews.next_cursor, error: "" };
  this.setState(tmpState);
},

previewsFailedToReceive: function(_){
  this.setState(Object.assign({}, this.state, { error: "", isLoading: false, previews: [], nextCursor: "" }));
},

我收到以下 reactJS 错误:

Uncaught [object Object]

在线 1093 在 react.js 库中(在方法 invariant 中)。

如果我没有将任何复杂对象(在我的 previews 数据中)传递给状态,我不会收到错误消息。

知道我做错了什么吗?

编辑:这是整个组件,解决第一个答案,我仍然得到同样的错误。

var Creatives = React.createClass({
  getInitialState: function() {
    return { previews: [], isLoading: true, error: "", nextCursor: "" };
  },
  componentDidMount: function(){
    $.ajax("/my-url, {
      method: "GET",
      success: this.previewsReceived.bind(this),
      failure: this.previewsFailedToReceive.bind(this)
    });
  },
  previewsReceived: function(previews){
    var tmpState =  { isLoading: false, previews: previews.data, nextCursor: previews.next_cursor, error: "" };
    this.setState(tmpState);
  },

  previewsFailedToReceive: function(_){
    this.setState({ error: "", isLoading: false, previews: [], nextCursor: "" });
  },

  render: function() {
    return <ul>
      {this.state.previews.map(function(creative) {
        return <li key={creative.tweet_id} style="width: 450px">
          <input type="checkbox" style="float:left;margin-top: 10px" />
          <CreativePreview creative={creative} /></li>;
        })
      }
      </ul>;
  }
});

当我拨打bind 时,我还会收到以下警告:

Warning: bind(): You are binding a component method to the component.
React does this for you automatically in a high-performance way,
so you can safely remove this call. See Creatives

Edit2:我发现删除大部分渲染方法“修复”了错误。所以我也将发布该组件的定义:

var CreativePreview = React.createClass({
  render: function() {
    return <iframe
        id={ 'iframe-tweet-id-'+ this.props.creative.tweet_id }
        dangerouslySetInnerHTML={this.props.creative.preview}>
    </iframe>;
  }
});

【问题讨论】:

  • 你能粘贴整个组件吗?

标签: reactjs state


【解决方案1】:

我的代码中有几个错误:

  • html 标记中的内联 classstyle 假定实际的 html 约定而不是 jsx 格式。
  • iframe 很难在 reactJS 中实现。我发现了一个受 https://github.com/ryanseddon/react-frame-component 启发的解决方法,但由于它不能开箱即用,我在其中使用了 vanilla Javascript:

--

var CreativeFrame = React.createClass({

  render: function() {
    var style = { width: '420px', border: 'none', height: '280px' };
    return <iframe
        style={style}
        className="tweet-content"
        id={ "iframe-tweet-id-" + this.props.creative.tweet_id }>
    </iframe>;
  },
  componentDidMount: function() {
    this.renderFrameContents();
  },
  renderFrameContents: function() {
    // Proof that good old Javascript >> Any library
    var iframe = document.getElementById("iframe-tweet-id-" + this.props.creative.tweet_id);
    var iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
    iframeDoc.body.innerHTML = this.props.creative.preview;
  },
  componentDidUpdate: function() {
    this.renderFrameContents();
  },
  componentWillUnmount: function() {
    var doc = ReactDOM.findDOMNode(this).contentDocument;
    if (doc) {
      ReactDOM.unmountComponentAtNode(doc.body);
    }
  }
});

如果有人知道它的改进,请告诉我。

【讨论】:

    【解决方案2】:

    我认为 dangerouslySetInnerHtml&lt;iframe&gt; 元素上的工作方式不会像您希望的那样。

    您可以通过为您的&lt;iframe&gt; 元素创建一个ref 来直接填充它:

    var CreativePreview = React.createClass({
      componentDidMount: function(){
        var frame = React.findDOMNode(this.refs.myFrame);
        frame.document.body.innerHTML = this.props.creative.preview;
      },
      render: function() {
        return <iframe ref='myFrame' />;
      }
    });
    

    错误很可能出现在CreativePreview 中。尝试删除它,看看它是否能解决您的问题。

    旁注:Object.assign() 调用对于 React 的 setState 是不必要的。 setState 方法会自动与当前状态合并。

    编辑: 似乎 React 现在会为组件函数自动绑定 this

    编辑 2: 现在我们可以看到CreativePreview

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-03
      • 1970-01-01
      • 2021-08-23
      • 1970-01-01
      • 1970-01-01
      • 2015-11-21
      • 2021-01-24
      • 1970-01-01
      相关资源
      最近更新 更多