初学rails和ReactJS不久,也分别在看rails和ReactJS的官方文档,至于这两者的轻重缓急,公司里带我的同事是这样说的:
“先看React的文档吧,相对rails来说,React的开发思路更绕,也可以说是React的设计思路更加新颖。”
确实,一开始上手React很容易就学会了怎么写交互性控件,能实现数据的展示和动态更新,后来发现这只是个开始。我还没形成很清晰的React组件开发思路,里面有很多很模糊的地方。下面说说我的困惑:
这段时间看了一些文档和博客,对这些问题有了一定的了解,props vs state这篇博客说得比较全面,特地翻译了一下,希望能帮到大家。
从我们开始使用React在uberVU (现在是 Hootsuite)重建UI起,开发者问得最多的问题大概是:
props和state的具体区别在哪?
理解他们如何工作相当容易,特别是在对应的上下文中,但在概念上理解他们也有点困难。首先困惑着我们的是,他们都有抽象的术语和相同的值,却有着很不一样的规则。
一个组件的主要责任是将原始数据转化为丰富的HTML,请记住这点。props和state共同构成原始数据,原始数据构成HTML。你可以说 props 和 state 是一个组件render()
函数的输入数据,所以我们需要深入进去看看每个数据类型代表什么以及从哪里来的。
在区分props和state之前,我们先看看这两者的共同点:
如果一个组件需要在某个时间点改变某个属性,那该属性应设为state,否则应设为组件的prop。
props (properties的简称) 是一个组件的 配置选项 。 props是由上到下指定且不可改变的。
一个组件不能改变自身的props, 但要负责设置子组件的 props。
当组件加载时,state有一个默认值,后来state会不定期地改变(主要是用户行为触发的)。state是每一时间点组件状态的代表-快照。
一个组件在内部管理自己的state,除了设置子组件的state之外,该组件与其子组件的state没有任何联系。你可以认为state是私有的。
- | props | state |
---|---|---|
能否从父组件获取初始值? | Yes | Yes |
能否被父组件改变? | Yes | No |
能否在组件内设置默认值?* | Yes | Yes |
能否在组件内改变? | No | Yes |
能否设置子组件的初始值? | Yes | Yes |
能否在子组件中改变? | Yes | No |
*注意:props 和 state 从父组件获取的初始值都会被在组件内设置的默认值覆盖。
state 是可选项,不是React强制实现的。因为state增加了组件的复杂度同时降低了组件的可预见性,所以没有state的组件 要略胜一筹。即便在一个交互式应用中,你显然离不开state,你也要避免有太多的有状态化组件(含有state的组件)。
render()
函数和所有围绕props的逻辑之外,没有什么要关心的地方。这使他们易于理解且易于测试译者标注为重要内容:这些逻辑实现应该封装在一个含有中等数量state的有状态组件中,而所有可视化和格式化的逻辑实现应该尽可能封装在多个无状态组件中。
补充官网文档里如何判别某一变量应设为state还是prop:
大部分组件的工作应该是从 props 里取数据并渲染出来。但是,有时需要对用户输入、服务器请求或者时间变化等作出响应,这时才需要使用 State。
尝试把尽可能多的组件无状态化。 这样做能隔离 state,把它放到最合理的地方,也能减少冗余,同时易于解释程序运作过程。
常用的模式是创建多个只负责渲染数据的无状态(stateless)组件,在它们的上层创建一个有状态(stateful)组件并把它的状态通过 props 传给子级。这个有状态的组件封装了所有用户的交互逻辑,而这些无状态组件则负责声明式地渲染数据。
State 应该包括那些可能被组件的事件处理器改变并触发用户界面更新的数据。 真实的应用中这种数据一般都很小且能被 JSON 序列化。当创建一个状态化的组件时,想象一下表示它的状态最少需要哪些数据,并只把这些数据存入 this.state。在 render() 里再根据 state 来计算你需要的其它数据。你会发现以这种方式思考和开发程序最终往往是正确的,因为如果在 state 里添加冗余数据或计算所得数据,需要你经常手动保持数据同步,不能让 React 来帮你处理。
this.state 应该仅包括能表示用户界面状态所需的最少数据。因此,它不应该包括:
看完上面的文章之后,我解决了几个问题:
这是第一次翻译别人的文章,我觉得要比自己看几遍理解得都要深刻,所以这是一次好的尝试。希望自己能找到更多好文章,学得更多。