Reactjs 状态vs道具

Reactjs 状态vs道具,reactjs,Reactjs,这可能是在回答问题和固执己见之间徘徊,但我会反复讨论如何随着复杂性的增长构建ReactJS组件,并可能会用到一些方向 来自AngularJS,我想将我的模型作为属性传递到组件中,并让组件直接修改模型。或者我应该将模型拆分为各种状态属性,并在向上游发送时将其编译回一起?怎么办? 以博客帖子编辑器为例。尝试直接修改模型的结果如下所示: var PostEditor = React.createClass({ updateText: function(e) { var text = e.t

这可能是在回答问题和固执己见之间徘徊,但我会反复讨论如何随着复杂性的增长构建ReactJS组件,并可能会用到一些方向

来自AngularJS,我想将我的模型作为属性传递到组件中,并让组件直接修改模型。或者我应该将模型拆分为各种
状态
属性,并在向上游发送时将其编译回一起?怎么办?

以博客帖子编辑器为例。尝试直接修改模型的结果如下所示:

var PostEditor = React.createClass({
  updateText: function(e) {
    var text = e.target.value;
    this.props.post.text = text;
    this.forceUpdate();
  },
  render: function() {
    return (
      <input value={this.props.post.text} onChange={this.updateText}/>
      <button onClick={this.props.post.save}/>Save</button>
    );
  }
});
这不需要调用This.forceUpdate(),但随着模型的发展,(一篇文章可能有作者、主题、标签、评论、评级等),组件开始变得非常复杂


第一种方法是可行的吗?

你的第二种方法更像它。React与其说关心模型,还不如说关心值以及它们如何在应用程序中流动。理想情况下,post模型将存储在根目录下的单个组件中。然后创建子组件,每个子组件使用模型的各个部分

您可以将回调传递给需要修改数据的子级,并从子组件调用它们

直接修改this.props或this.state不是一个好主意,因为React将无法识别更改。这是因为React会对你的post道具做一个肤浅的比较,以确定它是否发生了变化

我这样做是为了展示数据如何从外部组件流向内部组件

handleClick
方法显示了3种(im)正确更新状态的方法:

var Outer=React.createClass({
getInitialState:函数(){
返回{data:{value:'首先,它工作'}};
},
handleClick:函数(){
//1.这不起作用,渲染未触发。
//切勿直接设置状态,因为更新的值
//仍然可以读取,这可能导致意外行为。
this.state.data.value='但是React永远不会知道!';
//2.这是可行的,因为我们使用setState
var newData={value:'it works 2'};
this.setState({data:newData});
//3.或者,您可以使用React的不变性帮助程序
//更新更复杂的模型。
//阅读更多:http://facebook.github.io/react/docs/update.html
var newState=React.addons.update(this.state{
数据:{value:{$set:'it works'}
});
this.setState(newState);
},
render:function(){
返回;
}
});
来自React文档

道具是不可变的:它们从父级传递,并由父级“拥有”。为了实现交互,我们将可变状态引入组件。this.state是组件专用的,可以通过调用this.setState()进行更改。当状态更新时,组件将重新呈现自身


来自TrySpace:当道具(或状态)更新时(通过setProps/setState或父级),组件也会重新呈现。

更新2016: 反应发生了变化,“道具与状态”的解释变得非常简单。如果组件需要更改数据,请将其置于状态,否则在props中。因为道具现在是只读的

道具和状态的确切区别是什么

你可以找到很好的解释(完整版)

阅读:

让我们逐一检查,找出哪一个是状态。简单地 就每一条数据问三个问题:

  • 它是通过道具从父母那里传来的吗?如果是的话,很可能不是 国家
  • 它会随着时间变化吗?如果不是,它可能不是州

  • 你能根据你生活中的任何其他状态或道具来计算它吗 组件?如果是这样,那就不是州政府了


  • 我不确定我是否在回答你的问题,但我发现,特别是在大型/不断增长的应用程序中,容器/组件模式工作得非常好

    基本上,您有两个组件:

    • “纯”显示组件,处理样式和DOM交互
    • 容器组件,用于访问/保存外部数据、管理状态和呈现显示组件
    例子 N.B.这个例子可能太简单,无法说明这种模式的好处,因为对于这样一个简单的案例来说,它非常冗长

    /**
    *容器组件
    *
    *-管理组件状态
    *-是否执行数据获取/保存操作
    */
    var PostEditorContainer=React.createClass({
    getInitialState:函数(){
    返回{
    案文:“”
    };
    },
    componentWillMount:function(){
    这是我的国家({
    文本:getPostText()
    });
    },
    updateText:函数(文本){
    这是我的国家({
    文本:文本
    });
    },
    savePost:function(){
    savePostText(this.state.text);
    },
    render:function(){
    返回(
    );
    }
    });
    /**
    *纯显示元件
    *
    *-根据传递的属性计算样式
    *-通常只是一种渲染方法
    *-使用从容器传入的方法来宣布更改
    */
    var PostEditor=React.createClass({
    render:function(){
    返回(
    );
    }
    });
    
    利益 通过将显示逻辑和数据/状态管理分开,您就有了一个可重用的显示组件:

    • 可以很容易地使用不同的道具进行迭代,例如
    • 可以使用不同的容器包装不同的行为(或与其他组件组合以构建应用程序的更大部分)
    您还有一个处理所有外部通信的容器组件。这将使您在以后进行任何重大更改时能够更灵活地访问数据*

    这种模式还使得编写和实现单元测试更加简单

    var PostEditor = React.createClass({ getInitialState: function() { return { text: "" }; }, componentWillMount: function() { this.setState({ text: this.props.post.text }); }, updateText: function(e) { this.setState({ text: e.target.value }); }, savePost: function() { this.props.post.text = this.state.text; this.props.post.save(); }, render: function() { return ( <input value={this.state.text} onChange={this.updateText}/> <button onClick={this.savePost}/>Save</button> ); } });