将 UI 划分为组件树的形式
在传统模式下,我们的思维方式是:
- 创建
html
模版 - 通过
javascript
拿到页面数据,并展示到页面 - 监听
form
数据,对submit button
绑定提交事件
如果是 React Component,可以将页面拆分如 ⬇️:
以及代码形式:
class CommentBox extends Component {
render() {
return (
<div class="comment-box">
<h1>Comments(3)</h1>
<CommentList />
<CommentForm>
</div>
);
}
}
复制代码
显而易见,这种拆分方式使结构更简单、更清楚。
什么是 React 组件
组件允许你将 UI 拆分为独立可复用的代码片段,并对每个片段进行独立构思。
组件,从概念上类似于 JavaScript
函数。它接受任意的入参(即 props
),并返回用于描述页面展示内容的 React
元素。
( props: 外部传入的属性;state:内部维护的状态 )
React 组件的三个特征:
- 组件一般不提供方法,而是一种状态机(状态是什么,结果就是什么)
- 组件可以理解为一个纯函数(参数与结果对应)
- 单向数据流( 父组件可以向子组件传递
props
,但子组件不能修改父组件传递来的props
,子组件只能通过event
通知父组件进行数据更改。)
创建一个简单的 React 组件
这三个点是否清楚
创建组件要考虑的三个方面:
- 创建静态 UI
- 考虑组件的状态组成( 受控组件 or 非受控组件 )
- 考虑组件的交互方式( 组件内部与组件使用者 )
受控组件 vs 非受控组件
受控组件:表单元素状态由使用者维护
以 input
为例,需要指定 value
和 onChange
;value
的值取决于外部传入什么,而不是用户输入什么
<input value={this.state.inputMsg} onChange={this.handleChange} />
复制代码
非受控组件:表单元素状态由 DOM 自身维护
不需要指定 value
和 onChange
,但外界需要通过原生 DOM Node
才可以拿到 value
。
<input ref={(node) => (this.input = node)} />
复制代码
设计流程
- 拆分 UI
- 构建应用的静态版本( 应使用
props
,而避免state
) - 添加交互功能,即触发基础数据模型改变的能力。(此时用到
state
) - 确定
state
的位置,即哪个组件能够改变这些state
,或者说拥有这些state
。 - 添加反向数据流
需要注意的是:
- 最好将渲染
UI
和添加交互这两个过程分开。这是因为,一个应用的静态版本,往往要需要大量代码,而不需要考虑太多交互细节;添加交互功能时则要考虑大量细节,而不需要编写太多代码。 - 当你的应用比较简单时,使用自上而下的方式更方便;对于较为大型的项目来说,自下而上地构建,并同时为低层组件编写测试是更加简单的方式。
- 应该找出应用所需的 state 的最小表示,并根据需要计算出其他所有数据。比如,一个任务清单应用,你只需要保存一个包含所有事项的数组,而无需额外保存一个单独的
state
变量(用于存储任务个数,用length
就可以获取)。
创建组件的两个原则
何时创建组件:单一职责原则
因为组件是构建 UI 的最小元素,所以需要做到这两点:
- 每个组件只做一件事~
- 如果组件变得复杂,应该拆分为多个小组件
这样做的好处不仅可以拆分复杂度,还可以提高性能;页面的刷新可以锁定在更小的范围。
数据状态管理:DRY 原则
DRY: Don’t Repeat Yourself
- 能计算得到的状态不要单独存储
- 组件尽量无状态,所需数据由
props
获取,有利于组件的复用
参考资料
- React 理念:zh-hans.reactjs.org/docs/thinki…
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END