前言:
数据的传递是代码开发重要的一节,在 React 数据是怎么传递的呢?
→ 单向数据流
开始之前,我们需要大概认知一下 React 的数据传输形式:
在 React 中,数据的流向是单向的(即 从父节点传递到子节点);如果顶层组建的某个 prop 改变了,React 会递归
地向下遍历整棵组件树,重新渲染所有使用这个 prop 的组件。
在 React 组件内部还有自己的状态 state,它只能在组件内部修改。同样它的改变也会促发 render 函数重新渲染
DOM Tree。
>
对于 props 和 state,我们可以这样理解:props 和 state 共同构成原始数据,原始数据构成HTML,也可以理解 props
和 state 是一个组件render()函数的输入数据。
目录:
- props
- state
- 什么时候使用 props 和 state
props →
是什么?
React 中组件的一个对外属性,用来:接收外部 传递的 任意类型数据
怎么用?
挂载组件时设置组件的 props
const title = { title : '例子'} <Example className='t1' title={title}/>
setProps( )方法(尽量避免)
通过调用组件实例的 setProps( )方法可以来设置props,但是不能再组件内部调用,或者直接修改 this.props, 这会违背组件设计原则。 我们应避免修改props,要把props作为数据源
propTypes 验证 props
随着应用不断变大,保证组件被正确使用变得非常有用。为此 React 引入 propTypes。React.PropTypes 提供很多验证器 ( validator ) 来验证传入数据的有效性。当向 props 传入无效数据时,JavaScript 控制台会抛出警告。注意为了性能考虑,只在开发环境验证 propTypes。
由于篇幅和美观原因,示例代码省略,请大家见谅。
getDefaultProps
getDefaultProps 函数用来设置默认属性 const Example = React.createClass({ getDefaultProps : function(){ return{ title : 'example', description : '说明', }; } ... });
注意: getDefaultProps 并不是在组件实例化时被调用,而是在执行到 React.createClass 的时候就被调用了,返回值会被缓存起来。我们不能再 getDefaultProps 中使用任何特定的实例数据!我初学还真犯过这点错误……
state →
state 是什么?
React 中组件的对内的属性,用来:存储简单的视图状态
怎么用?
getInitialState方法
设置默认的 state 属性值
setState 方法
只要 setState 被调用,render 就会被调用,如果 render 返回值有变,虚拟 DOM 就会更新,真实 DOM 重新渲染。
注意:对 state 重新赋值 不可直接修改 this.state,原因同 this.props
什么时候使用 props 、 state →
我在实践中,使用props和state处理数据,代码组件不多的时候,很好处理。但随着代码、组件数的增多,往往会出现很
多不可预测性的bug和逻辑错误。
- 那到底应该在什么时候使用 props、state 呢?
下面,我把几篇关于props 和 state的文章进行总结:
1. 我们首先来总结一下 怎么改变 props 和 state
情况 props state 能否从父组件获取初始值? Yes Yes 能否被父组件改变? Yes No 能否在组件内设置默认值? Yes Yes 能否在组件内改变? No Yes 能否设置子组件的初始值? Yes Yes 能否在子组件中改变? Yes No 注意:props 和 state 从父组件获取的初始值都会被在组件内设置的默认值覆盖。
简而言之:props组件外改变,state组件内改变;都能从父组件获取初始值,设置子组件初始值。
2. 哪些组件应该有 State?state 是可选项,不是 React 强制实现的。因为 state 增加了组件的复杂度同时降低了组件的可预见性,所以没有 state
的组件要略胜一筹。即便在一个交互式应用中,你显然离不开state,你也要避免有太多的含有state的组件。
– —- — —— —– — —- ——- - —- — —- – – – 常用的模式 → — — - - — — ——– — – — ——- – — – - - - - *:
创建多个只负责渲染数据的无状态(stateless)组件,在它们的上层创建一个有状态(stateful)组件并把它的状态通过 props 传给子级。这个有状态的组件封装了所有用户的交互逻辑,而这些无状态组件则负责声明式地渲染数据。
– —- — —— —– — —- ——- - —- — —- – – – —— — — - - — — ——– — – — ——- – — – - - - - *:
3. 哪些 应该 作为 State?State 应该包括那些可能被组件的事件处理器改变并触发用户界面更新的数据。 真实的应用中这种数据一般都很小且能被
JSON 序列化。当创建一个状态化的组件时,想象一下表示它的状态最少需要哪些数据,并只把这些数据存入 this.state。
在 render() 里再根据 state 来计算你需要的其它数据。
4. 哪些 不应该 作为 state?
- 计算所得数据
- React 组件: 在 render() 里使用当前 props 和 state 来创建它。
- props数据: 不要尝试把 props 复制到 state 中,尽可能 把它当作数据源(只读 props)