This is commonly called a "top-down" or "unidirectional" data flow. Any state is always owned by some specific component, and any data or UI derived from that state can only affect components "below" them in the tree.
If you imagine a component tree as a waterfall of props, each component's state is like an additional water source that joins it at an arbitrary point but also flows down.
Components and Props
组件可以将UI分割为独立,可复用块,并且以组件化方式管理这些块。
理论上来说,组件类似于JS中的函数。它们都接受任意的输入(称为'props')然后返回描述如何展现于屏幕的React elements。
函数式组件和类组件
函数式组件:
类组件:
渲染一个组件
React elements不仅可以由DOM标签构成,用户自定义标签也可:
当React检测到一个elements中为自定义标签,会将JSX属性作为一个对象传递给这个组件,也即
props
:流程为:
<Welcome name="Sara">
{ name: "Sara" }
作为props
传入<h1>Hello, Sara</h1>
复合组件
组件可以在输出中调用其他组件
props
是只读的React组件必须遵循"永远不改变输入值"这一准则 在下一节中会介绍State这一个概念,如何在不违背这一准则的前提下修改状态。
State and Lifecycle
目前为止我们只学习了一种更新视图的方法(即不断地给ReactDOM.render()传入新的参数)。 如何让组件自更新,而不是依靠我们操作来实现更新呢? 方法就是state,而state只能在类组件中进行创建。
将函数组件转换为类组件
转换为:
为类组件添加本地状态
为类组件添加生命周期方法
在拥有诸多组件的应用内,适时释放被摧毁组件占用资源是非常重要的。 我们可以选择在组件刚渲染到DOM时为Clock开启一个定时器,在组件被摧毁之前将其关闭,这些方法被称为生命周期钩子。 代码如下:
分析上述代码执行过程:
<Clock />
被传递给ReactDOM.render()
,React调用该组件中的构造器。由于Clock需要展示当前时间,它初始化了this.state
。之后我们会来更新这个state
render()
方法。在这里React可以清楚应当在视图中呈现什么。之后更新DOM匹配渲染结果componentDidMount()
钩子。在这个钩子内部,创建一个定时器:每1秒调用tick()
tick()
。在该方法内部,Clock组件通过调用setState
并传递一个对象来更新视图,由于setState()
被调用,React知道状态改变了,于是再去调用render()
方法来了解更新后的视图呈现内容...componentWillUnmount()
钩子销毁定时器。正确使用State
setState()
调用,以便优化性能。由于this.props
和this.state
可能会异步更新,所以你不应该依赖于它们去计算下一个state。 举例:应该使用
setState
的第二种形式——函数体,接受两个参数,第一个为之前的state,第二个为更新时的props。State更新会合并 这意味着为
setState()
传递参数可以只传State
的一部分,而React会进行浅合并,更改变化的部分,保留未改变的部分:数据流方向-自上而下