最近在看Fullstack React: The Complete Guide to ReactJS and Friends
,发现这本书写的还是不错的,从前到后写的相当详细,还提供了一些如何设计React
程序的方法论,我这里把关键点摘抄下来。
下边这些思想,也可以在React 哲学找到。
从头创建React
程序的步骤
这一段来自这本书PDF版的86页,原文如下:
The steps for building React apps from scratch:
- Break the app into components
- Build a static version of the app
- Determine what should be stateful
- Determine in which component each piece of state should live
- Hard-code initial states
- Add inverse data flow
- Add server communication
翻译如下:
从零开始创建React应用的步骤:
- 将应用拆分到组件
- 创建一个静态版的应用
- 确定哪些数据应该位于
state
中 - 确定
state
应该位于什么组件中 - 硬编码初始的
state
- 添加反向数据流(即叶子组件通过事件改变
state
) - 添加和后端的通信功能
这里边第三项和第四项,还得单独拿出来说说。
确定哪些数据应该位于state
中
这一段来自于书的97页,也非常重要。
Determine what should be stateful:
- Is it passed in from a parent via props? If so, it probably isn’t state.
- Does it change over time? If not, it probably isn’t state.
- Can you compute it based on any other state or props in your component? If so, it’s not state.
翻译如下:
- 该数据是否是由父组件通过 props 传递而来的?如果是,那它应该不是
state
。 - 该数据是否随时间的推移而保持不变?如果是,那它应该也不是
state
。 - 你能否根据其他 state 或 props 计算出该数据的值?如果是,那它也不是 state
state
。 - 表单中存放的数据,要使用
state
。
第一项很好理解,一般通过props
传入的数据,都是父组件交给子组件用于继续传递或者渲染的内容,如果要变化,变化传入的就行了,而不是在接收到props
这一层把它当成state
。
第二项也很好理解,如果不变动,那可能是死数据,不用理睬。第三点就更好理解了,如果是基于其他数据计算出来的结果,那自身的存在就是一个计算过程,无需保存state
。第四条是这本书讲到后边提到的,对于表单组件,由于要及时反应表单组件内容与实际存储数据的变化联系,所以表单组件都要维持自己的state
,在表单进行提交的时候,去更新更高级别的state
或者和服务器通信。
确定state
放在何处
这一段来自于书的99页,state
要放在哪个组件中比较合理呢。
Determine in which component each piece of state should live:
- Identify every component that renders something based on that state.
- Find a common owner component (a single component above all the
components that need the state in the hierarchy). - Either the common owner or another component higher up in the
hierarchy should own the state. - If you can’t find a component where it makes sense to own the state, create a new component simply for holding the state and add it somewhere in the hierarchy above the common owner component.
翻译如下:
- 找到根据这个
state
进行渲染的所有组件 - 找到他们的共同所有者(
common owner
)组件(在组件层级上高于所有需要该state
的组件) - 该共同所有者组件或者比它层级更高的组件应该拥有该
state
- 如果你找不到一个合适的位置来存放该
state
,就可以直接创建一个新的组件来存放该state
,并将这一新组件置于高于共同所有者组件层级的位置
其实这个也很好理解,类似于以前学原生JS
时候遇到事件捕捉,会把事件捕捉器安放在所有要发生事件的元素的共同祖先那里,这样冒泡的时候就可以捕捉到是哪个元素发生事件。
我记得刚开始接触前端的时候,大概2015年,三大框架Vue
, React
和Angular
打的火热,但到现在七八年过去了,其实最流行的框架只剩下React
了,这是因为React
的设计非常清晰,数据单向流动,枝叶组件通过事件反向影响state
,相比之下Vue
给我的感觉就是小作坊开发,乱加各种想法和功能,反而让整个程序非常的不清晰。
更新state
的时候给setState
方法传入一个函数
这个来自于官方教程的State
的更新可能是异步的。这是因为JS
的单线程异步队列机制,更新操作会被压入队列中,导致如果直接传对象,获得的state
和props
的值未必正确,所以最好一律采用传入函数的方法。
这个函数两个参数就是上一个state
和当前的props
,保证多次更新也不会出错。
与后端交互的心得
在与后端交互的时候,如果本地有保存state
,常见的做法是在响应的事件里先进行本地状态的更新,然后再去更新服务端的信息。这样可以让组件立刻先行刷新(因为调用了setState
方法),整个应用响应更加快速。
11月18日后记:
Fullstack React: The Complete Guide to ReactJS and Friends
这书写的确实好,我把对应的中文版React
全家桶 前端开发与实例详解买回来了。
还有一个很棒的教程,就是我以前提过的React.js
小书。
这两本书搭配真是绝了,React.js
小书教你自己实现React
组件,接着老外的书教你自己实现React-Router
,最后再一起教你实现Redux
。
以后凡是再简单的页面,我也要用React
来写。