2

我正在使用 React.js 构建我的整个网站,如下所示:

     React.render(
       <div id="mainWrapper">
         <MainHeader />
         <div id="contentWrapper" className="contentWrapper">
           <MainFlow data={example_data} />
           <AddElementWrapper data={activities} />
         </div>
       </div>,
       document.body
     );

但是,在我的一个数据保存组件(即 MainFlow 或 AddElementWrapper)上调用 setProperties 时,我收到一个错误,指出我应该通过它们的父级操作数据。

Uncaught Error: Invariant Violation: replaceProps(...): You called `setProps` or `replaceProps` on a component with a parent. This is an anti-pattern since props will get reactively updated when rendered. Instead, change the owner's `render` method to pass the correct value as props to the component where it is created.

首先:我认为只有当我要操作的组件有另一个所有者时,这才会成为问题。但是,我的组件没有 React 组件作为owner,只有 HTML 元素作为parents

我可以通过将所有应用程序数据附加到单个根组件来规避这个问题。但是,我想将某些数据集分开。有办法吗?

4

3 回答 3

2

您应该定义一个 Wrapper 组件并在那里维护数据的状态,并在数据从外部世界发生变化时简单地调用 setState。

Wrapper = React.createClass({
getInitialState: function() {
    return {example_data: example_data, activities: activities};
},
refresh: function() {
    this.setState({example_data: this.state.example_data, activities: this.state.activities});
},
render: function() {
    return (
        <div id="mainWrapper">
            <MainHeader/>
            <div id="contentWrapper" className="contentWrapper">
                <MainFlow data={this.state.example_data} />
                <AddElementWrapper data={this.state.activities} />
            </div>
        </div>
    );
  }
});

React.render(<Wrapper/>);
于 2014-11-20T19:59:26.003 回答
1

您可以将道具复制到子组件的状态,然后更改状态。

在 MainFlow 和 AddElementWrapper 组件中,您可以使用:

 getInitialState: function() {
  return {activities: this.props.data};
 },

然后您可以使用 this.state.activities 并使用 setState({activities: yourObject }) 对其进行修改

于 2014-11-20T19:48:13.817 回答
1

这个想法是让 React 组件显式地监听数据变化。为此,您将在组件安装时设置回调。

我建议寻找两件事:Backbone+React(和 BackboneReact mixin)或 Flux+React。

Flux 方式是拥有一个关于数据可用性的全局事件系统(调度程序),而主干方式是注册到特定的 Collection 事件。

这段代码直接来自 TodoMVC React-backbone 项目的 BackboneMixin:

componentDidMount: function() {
  // Whenever there may be a change in the Backbone data, trigger a
  // reconcile.
  this.getBackboneCollections().forEach(function(collection) {
    // explicitly bind `null` to `forceUpdate`, as it demands a callback and
    // React validates that it's a function. `collection` events passes
    // additional arguments that are not functions
    collection.on('add remove change', this.forceUpdate.bind(this, null));
  }, this);
},

更多的 :

于 2015-02-03T16:55:58.760 回答