React(十一)- React拓展:Fragment、Context及PureComponent
发布日期:2021-05-07 14:50:27 浏览次数:25 分类:技术文章

本文共 5034 字,大约阅读时间需要 16 分钟。

React(十一)- React拓展:Fragment、Context及PureComponent

一. Fragment拓展

案例如下:

jsx语法中,render()里面最外层的标签,同级的不能有两个,如下

在这里插入图片描述
可以使用Fragment包起来,来解决上述问题:
在这里插入图片描述

二. Context拓展

Context,一种组件通信方式,常用于祖组件子类组件之间的通信。

案例如下:

首先,页面效果如图:

在这里插入图片描述
项目结构:
Demo组件:

import React, {    Component } from 'react'import './index.css'const MyContext = React.createContext()const {    Provider, Consumer } = MyContextexport default class A extends Component {       state = {    username: 'tom', age: 18 }    render() {           const {    username, age } = this.state        return (            

我是A组件

我的用户名是:{ username}

) }}class B extends Component { render() { return (

我是B组件

) }}// 类式组件的用法// class C extends Component { // // 声明接收context// static contextType = MyContext// render() { // const { username, age } = this.context// return (//
//

我是C组件

//

我从A组件中接收到的用户名是:{username}

//

我从A组件中接收到的年龄是:{age}

//
// )// }// }// 函数式组件的用法,必须使用到Consumer标签function C() { return (

我是C组件

我从A组件中接收到的用户名是:
{ value => `${ value.username},年龄是${ value.age}`}

)}

index.css文件:

.parent{       width: 500px;    background-color: orange;    padding: 8px;}.child{       width: 100%;    background-color: skyblue;    padding: 8px;}.grand{       width: 400px;    background-color: gray;    padding: 10px;}

从代码结构来看,A是父类,B是A的子类,C是B的子类,哪怕B没有传递对应的属性,C依旧可以获取到A类的值。

2.1 总结

  1. 创建Context容器对象:const xxx= React.createContext()

  2. 渲染子组件时,外面包裹xxx.Provider 标签,通过value属性给后代组件传递数据:

<子组件 />
  1. 后代组件读取数据:并且只要用xxx.Provider 包裹的一个子组件,那么该子组件以及其后代都能够直接获取到对应的数据,只需要声明接收context即可。
//第一种方式:仅适用类组件 // 声明接收context,contextType命名是固定的static contextType = xxxContext // 读取context中的value数据this.context   //第二种方式: 函数组件与类组件都可以
{ value => ( // value就是context中的value数据 要显示的内容 ) }

三. PureComponent拓展

这一小节主要来说说组件的优化,其实Component有2个问题

  1. 只要执行setState()即使不改变状态数据,。组件也会重新调用render()函数,效率低。

  2. 只当前组件重新render(),就会自动重新渲染子组件, 纵使子组件没有用到父组件的任何数据,效率低

效率高的情况是怎么样的呢?就是:只有当组件的stateprops数据发生改变时才重新调用render(),即不会收父组件以及setState()方法的影响。

案例1:

import React, {    Component } from 'react'import './index.css'export default class Parent extends Component {       state = {    carName: '奔驰' }    changeCar = () => {           this.setState({    carName: '宝马' })    }    render() {           console.log('Parent----render')        const {   carName} = this.state        return (            

我是Parent组件

车名:{ carName}
) }}class Child extends Component { render() { console.log('Child----render') return (

我是Child组件

我接收到的车是:{ this.props.carName}
) }}

页面效果:

在这里插入图片描述

点击换车按钮后可以发现:子组件也重新调用了render()进行了渲染。

在这里插入图片描述

那么如何对上述问题进行修改呢?

3.1 修改方案1

重写shouldComponentUpdate()方法:

import React, {    Component } from 'react'import './index.css'export default class Parent extends Component {       state = {    carName: '奔驰' }    changeCar = () => {           this.setState({    carName: '宝马' })    }    render() {           console.log('Parent----render')        const {    carName } = this.state        return (            

我是Parent组件

车名:{ carName}
) }}class Child extends Component { shouldComponentUpdate(nextProps, nextState) { return !this.props.carName === nextProps.carName } render() { console.log('Child----render') return (

我是Child组件

我接收到的车是:{ this.props.carName}
) }}

3.2 修改方案2

引用PureComponent

import React, {    PureComponent } from 'react'import './index.css'export default class Parent extends PureComponent {       state = {    carName: '奔驰' }    changeCar = () => {           this.setState({    carName: '宝马' })    }    render() {           console.log('Parent----render')        const {    carName } = this.state        return (            

我是Parent组件

车名:{ carName}
) }}class Child extends PureComponent { render() { console.log('Child----render') return (

我是Child组件

我接收到的车是:{ this.props.carName}
) }}

页面效果:

在这里插入图片描述

点击换车按钮后可以发现:子组件并没有调用render()

在这里插入图片描述

原理如下:

PureComponent重写了shouldComponentUpdate(),,只有stateprops数据有变化才返回true

注意:

  1. 只是进行stateprops数据的浅比较,如果只是数据对象内部数据变了,返回false
  2. 不要直接修改state数据,,而是要产生新数据。
上一篇:React(十二)- React拓展:renderProps、ErrorBoundary及组件间通信方式总结
下一篇:React(十)- React拓展:setState、lazyLoad以及Hook

发表评论

最新留言

网站不错 人气很旺了 加油
[***.192.178.218]2025年03月20日 11时32分40秒