组件通信
意义:就是组件间的数据传递
父子组件通信
父传子:使用props,在父组件中渲染子组件实例时,传递自定义属性数据给子组件
子传父:同样是利用props属性,父组件中渲染子组件实例时,将父组件的函数引用作为自定义属性值传递给子组件,子组件中需要向父组件传递数据时,调用在子组件属性中接收到的函数同时传递实际参数即可
跨组件跨层级通信
方法一:使用父子组通信方式进行传递数据
方法二: Context
方法三:使用状态管理库,如:redux、modx...
Context
Context提供了一个无需为每层组件手动添加props,就能在组件树间进行数据传递的方法。
可理解为使用Context实现组件树中全局状态数据共享。
API
- React.createContext()
- 创建Context对象,在createContext()调用时,可以传递参数作为Context中保存数据的初始值
- Context.Provider
- 这是生产组件,可以理解为向Context中保存数据的组件。
- Provider组件允许消费组件(Consumer)订阅context的变化。
- Provider组件有一个value属性,其值可以传递给后代组件中Consumer渲染时使用。
- 由于Consumer会订阅Context的变化,所以当Provider的
value发生变化时,它内部的所有消费组件都重新渲染。
- Context.Consumer
- 这是消费组件,订阅context变化。
- Consumer组件渲染时,需要传递一个函数作为子元素,该函数的参数为最近的Provider组件的value属性值,函数的返回值是一个React节点
- class.contextType
- 这是class组件中定义的静态属性,将contextType设置为一个有React.createContext()创建的对象,则在类得到成员方法中可以调用
this.context获取到最近Provider上提供的value值。
- 这是class组件中定义的静态属性,将contextType设置为一个有React.createContext()创建的对象,则在类得到成员方法中可以调用
Ref
引用DOM节点或组件实例
- 可使用字符串ref,在js逻辑中,调用
this.refs.xxx获取相关节点(该方法已弃用) - 使用Ref对象,调用React.createRef()方法,创建Ref对象,然后将其绑定到指定节点,在Ref对象的current属性中保存了绑定DOM节点对象实例
组件生命周期
挂载
当组件实例被创建并插入DOM中时,其生命周期调用顺序如下:
- constructor():用于初始化组件实例对象,通常在构造方法中初始化state和绑定方法的this指向
- static getDerivedStateFromProps():这是挂载与更新阶段都会调用到的方法,返回一个对象用于更新state,比如任何时候state的值都依赖于props的值时,可以调用这个方法处理。
- render():渲染React节点。纯函数(特点:返回值依赖于参数,函数主体不包括任何副作用操作)
- componentDidMount():会在组件挂载后(插入DOM树中)立即调用。依赖于DOM节点的初始化应该放在这里。如需通过网络请求获取数据,此处是实例化请求的好地方。
componentwillMount():现在这个生命周期钩子已弃用,不建议使用,这是在render()之前被调用到。这个方法后被命名为UNSAFE_componentWillMount()
更新
当组件的`props`或`state`发生变化时会触发更新
- static getDerivedStateFromProps():
- shouldComponentUpdate():这个方法通常作用性能优化方式存在。该方法返回Boolean值,当返回true表示继续向后渲染更新,返回false中断渲染。
- render():重新渲染
- getSnapshotBeforeUpdate():
- componentDidUpdate():更新结束后立即调用
卸载
当组件从DOM中移除时会调用如下方法
componentWillUnmount():会在组件卸载及销毁之前直接调用。通常可清理的资源有:清除timer,取消未完成的网络请求,移除自己添加过的事件监听(addEventListener/removeEventListener)....