在 React 组件中,代码重用的主要方式是组合而不是继承。
We strongly recommend against creating your own base component classes. In React components, code reuse is primarily achieved through composition rather than inheritance.
这句话来自于react的官方网站
为什么要提及这句话呢。因为现在我的项目中也有自己的创建的组件类,然后其余的组件来继承它。
其实最开始我也是一步一步的使用class App extends React.Component
来写我自己的组件,这样确实有点复杂,但是还算过得去。或许是因为初学react或者是对react的了解不深入,所以,一直就这样。去年了解了一下同事的安卓开发,他们都会建一个基础的类来继承于这个类,这个基础的类实现了一些公用的方法,所以继承于这个基础类的组件也会有这些方法,而且不用每一次都引入。这样理念确实很不错。自己用了一段时间,某些地方也确实方便,尤其是在组件数据请求的时候,需要渲染不同的组件(loading,completed,empty,request_error and so on),而且目前还没有发现有什么不一样的地方,因为这些继承于基础类的组件也是可以使用React的生命周期。直到今天,我才知道,原来这是违背了react的开发理念。那要怎么实现呢。正如上面所说
code reuse is primarily achieved through composition rather than inheritance.
通过组件的组合来实现,通过props
参数来实现,具体查看Composition vs Inheritance。
虽说这样开发可能会复杂一点(或许是自己的技术能力有限),不过这样也算是符合react的理念。
组件的生命周期
react组件的生命周期作为react开发人员面试的必考知识,还是很有必要实时掌握,并且实时更新。
React生命周期有一份图谱。上面可以查看react的生命周期(新版)。
react的组件的生命周期在react16.3及以后的版本中已经不一样了。但是总的几个阶段是不变的,不管是新的版本还是老的版本,都分为
- 组件挂载
- 组件更新
- 组件卸载
这样的几个阶段。
React16.3以前的生命周期(作为了解)
1.组件挂载
- getDefaultProps():加载的时候调用一次,设置默认的
props
,也可以使用组件名.defaultProps = {}
设置默认属性。 - getInitialState():加载的时候调用一次,可以初始化
state
。 - componentWillMount():只在组件挂载的时候调用,且整个生命周期只调用一次,此时可以修改
state
。但是一般不使用 - render():react的最重要的步骤,创建虚拟DOM,进行
diff算法
,更新DOM树都在此运行 - componentDidMount():组件渲染之后(执行rendeer后)调用一次
2.组件更新
- componentWillReceiveProps(nextProps):组件加载时不使用,组件接收新的
props
是调用 - shouldComponentUpdate(nextProps, nextState):组件接收到新的props或state时调用,函数必须有一个返回值(true or false),为
true
的时候组件更新,为flase
的时候组件不更新。默认返回的是true
。这个方法很重要,一个组件的优化都在这里面进行。 - componentWillUpdata(nextProps, nextState)
- render():react的最重要的步骤,创建虚拟DOM,进行
diff算法
,更新DOM树都在此运行 - componentDidUpdate():组件挂载时不调用,组件更新完成调用
3.卸载阶段
- componentWillUnmount():组件将要移除时候调用。一般在这个函数里面清除定时器,异步操作等
React16.3以后的生命周期
1.挂载阶段
- constructor():在这个构造函数中一般处理初始化state或者进行方法的绑定,如不需要,则可以不使用此方法
- static getDerivedStateFromProps():会在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用。它应返回一个对象来更新 state,如果返回 null 则不更新任何内容。
- render()
- componentDidMount()
*.componentWillMount方法在新的生命周期中已经过期,应该替换成UNSAFE_componentWillMount
,不过也将在react17中移除
2.更新阶段
- static getDerivedStateFromProps()
- shouldComponentUpdate()
- render()
- getSnapshotBeforeUpdate(prevProps, prevState):此方法并不常使用
- componentDidUpdate()
*. 老方法的componentWillUpdate
以及componentWillReceiveProps
即将过期,应该避免使用它们
3.卸载阶段
- componentWillUnmount()
错误处理
- static getDerivedStateFromProps()
- componentDidCatch(error, info):此生命周期在后代组件抛出错误后被调用
总的来说新的生命周期移除了一些不必要的函数。具体的可以查看React.Component
对 React 时间操作节流与防抖
- 节流:节流阻止函数在给定时间窗口内被调不能超过一次。
- 防抖:防抖确保函数不会在上一次被调用之后一定量的时间内被执行。当必须进行一些费时的计算来响应快速派发的事件时(比如鼠标滚动或键盘事件时),防抖是非常有用的。
以前在进行按钮提交,鼠标滚动等操作的时候,都会进行截留或者是防抖。但是都是自己写的,有时候或者是有的地方会忘记添加。
lodash中已经有相关的函数了
但是,整个 lodash 的库应用进来有1.4M,太大了。不过还好,npm 上面已经有 throttle 和 debounce 的提取包了。
https://www.npmjs.com/package/lodash.throttle
1
npm i --save lodash.throttle
https://www.npmjs.com/package/lodash.debounce
1
npm i --save lodash.debounce
都接收两个参数,第一个是操作的函数,第二个是时间间隔(ms)。