最近在看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来写。