React的组件中的props和state

请问React的组件(ES6的有状态组件)使用由父组件传递过来的props时
正确用法是将所有props和自身维护用的state都放置在state中,使用。还是分别this.props、this.state来使用呢?
2者在性能上有区别吗?
主流的做法是怎么样的呢?
谢谢

阅读 4.6k
4 个回答

看你的 props 是作为组件 state 某个属性的 defaultValue, 还是纯粹的渲染数据

正确用法是将所有props和自身维护用的state都放置在state中,使用。还是分别this.props、this.state来使用呢?

都可以,子组件的话就用父层组件传过来的props就好,除非你这个子组件有需要自己自行维护的state,才用state。从父层组件传来的props应该不需要再赋给自己的state,这有时候会造成反样式(anti-pattern),state是用于其中数据更动时要触发重渲染用的。

2者在性能上有区别吗?

state因为花费高,自然没有纯用props来得效率好。但这两者实际的目的性与作用不一样,不同地位比较难作比较。

主流的做法是怎么样的呢?

没有什么主流的作法,只有常见的作法而已。一般来说如果追求的是性能优化,子组件写得愈简单愈好,最好不要用本地端的state(local state),尽可能以函数型的组件样式为主。

假设你之后要改用Flux、Redux, MobX等数据流框架来管控整个应用领域的状态,那么只在父组件保持state,其它子组件中不要有,是基本的第一步。之后用了数据框架后,最好所有组件中都不要再用state这个东西,数据流框架有能力可以与组件的state沟通进行重渲染等工作,而且都已经有作性能上的优化。

既然官方都给分开了则有分开的道理,好不容易分开了,你再把他们给合并一块去,首先合并就会有额外的开销。合并之后,功能混杂,不好维护管理。

一.state

  1.state的作用

    state是React中组件的一个对象.React把用户界面当做是状态机,想象它有不同的状态然后渲染这些状态,可以轻松让用户界面与数据保持一致.

     React中,更新组件的state,会导致重新渲染用户界面(不要操作DOM).简单来说,就是用户界面会随着state变化而变化.

  2.state工作原理

    常用的通知React数据变化的方法是调用setState(data,callback).这个方法会合并data到this.state,并重新渲染组件.渲染完成后,调用可选的

    callback回调.大部分情况不需要提供callback,因为React会负责吧界面更新到最新状态.

  3.那些组件应该有state?

    大部分组件的工作应该是从props里取数据并渲染出来.但是,有时需要对用户输入,服务器请求或者时间变化等作出响应,这时才需要state.

    组件应该尽可能的无状态化,这样能隔离state,把它放到最合理的地方(Redux做的就是这个事情?),也能减少冗余并易于解释程序运作过程.

    常用的模式就是创建多个只负责渲染数据的无状态(stateless)组件,在他们的上层创建一个有状态(stateful)组件并把它的状态通过props

    传给子级.有状态的组件封装了所有的用户交互逻辑,而这些无状态组件只负责声明式地渲染数据.

  4.哪些应该作为state?

    state应该包括那些可能被组件的事件处理器改变并触发用户界面更新的数据.这中数据一般很小且能被JSON序列化.当创建一个状态化的组件

    的时候,应该保持数据的精简,然后存入this.state.在render()中在根据state来计算需要的其他数据.因为如果在state里添加冗余数据或计算

    所得数据,经常需要手动保持数据同步.

  5.那些不应该作为state?

    this.state应该仅包括能表示用户界面状态所需要的最少数据.因此,不应该包括:

      计算所得数据:

      React组件:在render()里使用props和state来创建它.

      基于props的重复数据:尽可能保持用props来做作为唯一的数据来源.把props保存到state中的有效的场景是需要知道它以前的值得时候,

      因为未来的props可能会变化.

   React中文文档

二.props

  1.props的作用

     组件中的props是一种父级向子级传递数据的方式.

  2.复合组件

 var Avatar = React.createClass({
   render: function() {
     return (
       <div>
         <ProfilePic username={this.props.username} />
         <ProfileLink username={this.props.username} />
       </div>
     );
   }
 });
 
 var ProfilePic = React.createClass({
   render: function() {
     return (
       <img src={'http://graph.facebook.com/' + this.props.username + '/picture'} />
     );
   }
 });
 
 var ProfileLink = React.createClass({
   render: function() {
     return (
       <a href={'http://www.facebook.com/' + this.props.username}>
         {this.props.username}
       </a>
     );
   }
 });
 
 React.render(
   <Avatar username="pwh" />,
   document.getElementById('example')
 );

原文

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题