前言
在React中,一切皆组件,React的组件可以分为两种,类组件和函数式组件,它们本质上是类和函数,同样拥有原型链,继承,静态属性等特性;但与常规的类和函数不同的是,React组件承载了渲染视图的UI和更新视图的setState、useState 等方法。
React对组件处理的流程
在React调和渲染fiber节点的时候,如果发现fiber tag是ClassComponet=1,则按照类组件逻辑处理,如果是FunctionComponet=0则按照函数组件逻辑处理。当然React也提供了一些内置的组件,比如说Suspense、Profiler等。
- 类组件的执行,是在
react-reconciler/src/ReactFiberClassComponent.js
中:
1 2 3 4 5 6 7 8
| function constructClassInstance( workInProgress, ctor, props ){ const instance = new ctor(props, context) }
|
- 函数式组件的执行,是在
react-reconciler/src/ReactFiberHooks.js
中:
1 2 3 4 5 6 7 8 9 10 11
| function renderWithHooks( current, workInProgress, Component, props, secondArg, nextRenderExpirationTime, ){ let children = Component(props, secondArg); }
|
类组件
类组件执行执行构造函数过程中会在实例上绑定props和context,初始化置空的refs属性,原型链上绑定setState、forceUpdate方法。对于updater,React在实例化组件之后会单独绑定update对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| function Component(props, context, updater) { this.props = props; this.context = context; this.refs = emptyObject; this.updater = updater || ReactNoopUpdateQueue; }
Component.prototype.setState = function(partialState, callback) { this.updater.enqueueSetState(this, partialState, callback, 'setState'); }
Component.prototype.forceUpdate = function(callback) { this.updater.enqueueForceUpdate(this, callback, 'forceUpdate'); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class Index extends React.Component{ constructor(...arg){ super(...arg) } state = {} static number = 1 handleClick= () => console.log(111) componentDidMount(){ console.log(Index.number,Index.number1) } render(){ return <div style={{ marginTop:'50px' }} onClick={ this.handerClick } >hello,React!</div> } } Index.number1 = 2 Index.prototype.handleClick = ()=> console.log(222)
|
函数组件
函数组件最开始又称无状态组件,在React v16.8之前只能渲染一些纯UI视图,或者通过context获取共享的状态
1 2 3 4 5 6
| function Index(){ console.log(Index.number) const [ message , setMessage ] = useState('hello,world') return <div onClick={() => setMessage('let us learn React!') } > { message } </div> } Index.number = 1
|
通过上面的源码我们知道,React底层在执行函数组件时,是直接采用执行函数的方法,不是采用new的方法,因此不要在函数组件的原型链上绑定属性和方法。
类组件和函数组件的本质区别
- 类组件底层只需要实例化一次,实例中保存了组件的state等状态,对于每一次更新只需要调用render方法以及对于的生命周期就可以了
- 函数组件每一次更新都是一个新的函数执行,里面的变量都会重新声明,所以才有了React Hooks,用于保存函数组件中的状态,执行一些副作用钩子等。
组件通信方式
React组件通信方式主要有以下五种:
- props和callback方式
- ref方式
- context上下文方式
- Redux、Mobx等状态管理的方式
- Event Bus事件总线
组件强化方式
React的类组件,有着良好的继承性,可以先针对一些基础组件,实现一部分功能,再针对项目要求进行改造,强化,添加额外功能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| class Person extends React.Component{ constructor(props){ super(props) console.log('hello , i am person') } componentDidMount(){ console.log(1111) } eat(){ } sleep(){ } ddd(){ console.log('打豆豆') } render(){ return <div> 大家好,我是一个person </div> } }
class Programmer extends Person{ constructor(props){ super(props) console.log('hello , i am Programmer too') } componentDidMount(){ console.log(this) } code(){ } render(){ return <div style={ { marginTop:'50px' } } > { super.render() } { /* 让 Person 中的 render 执行 */ } 我还是一个程序员! { /* 添加自己的内容 */ } </div> } } export default Programmer
|