一些React扩展知识——Fragment、Context和组件优化

文章介绍了React的Fragment用法,它允许在不添加额外DOM节点的情况下返回多个元素。接着讲解了Context,作为组件间通信的一种方式,以及其使用场景和注意事项。最后讨论了React组件的优化,包括不应无谓地重新渲染组件,可以通过重写shouldComponentUpdate或使用PureComponent来提高效率。
摘要由CSDN通过智能技术生成

一些React扩展知识

1. Fragment

有些时候render的函数里面返回的html模板必须在外面包一个div,但是这个Fragment就可以解决这个问题,可以包一个Fragement或者空标签

代码使用
//Fragement标签,Fragement允许写key值
<Fragment><Fragment/>
//空标签,空标签不允许写任何属性
<></>
作用

可以不用必须有一个真实的DOM根标签

2. Contex

理解

一种组件间的通信方式,常用于【祖组件】与【后代组件】间通信

使用
//创建Context容器对象,这个容器必须放在父子孙都能访问到的位置
const xxxContext=React.createContext()

//渲染子组件时,外面包裹xxxContext.Provider,通过value属性给后代组件传递数据;
<xxxContext.Provider value={数据}>
    子组件
</xxxContext.Provider>

//后代组件读取数据
//第一种方式:仅适用于类组件
static contextType=xxxContext   //声明接收context
this.context      //读取context中value的数据
//第二种方式:函数组件和类组件都可以
<xxxContext.Consumer>
    {
        value=>{//value就是context中的value数据
        要显示的内容}
    }
</xxxContext.Consumer>
注意

在应用开发中一般不用context,一般都用它的封装react组件

3. 组件优化

import React,{Component} from 'react'

export default class Parent extends Component{

    state={carName:"奔驰C36"}

    changeCar=()=>{
        this.setState({carName:'迈巴赫'})
    }
    render(){
        const {carName}=this.state
        return (
            <div>
                <h3>我是parent组件</h3>
                <span>我的车名字是:{this.state.carName}</span><br/>
                <button onClick={this.changeCar}>点我换车</button>
                <Child carName={carName}/>
            </div>
        )
    }
}

class Child extends Component{
    render(){
        return (
            <div>
                <h3>我是child组件</h3>
                <span>我接到的车是:{this.state.carName}</span>
            </div>
        )
    }
}

在上述例子中,如果父组件的数据更新了,父组件的render会调用一次,子组件的render也会调用一次

哪怕父组件不传数据给子组件,子组件的render也会调用一次,下面进行总结:

Component的两个问题
  1. 只要执行setState(),即便不改变状态数据,组件也会重新render()
  2. 只要当前组件重新render(),就会自动重新render子组件,纵使子组件没有用到父组件的任何数据==>效率低
效率高的做法

只有当组件的state或props数据发生改变的时候才重新render()

原因

Component中的shouldComponentUpdate()总是返回true

解决
//办法1:
    重写shouldComponentUpdate()方法
    比较新旧state和props数据,如果有变化才返回true,如果没有就返回false
//办法2:
    使用PureComponent
    PureComponent重写了shouldComponentUpdate(),只有state或props数据有变化才返回true
    注意:
        只是进行state和props数据的浅比较,如果只是数组对象内部数据变了,返回false
        不要直接修改state中数据,而是要产生新的数据
    项目中一般不用PureComponent来优化

下面就上面的例子,分别列举解决办法,首先是自定义shouldComponentUpdate:

import React,{Component} from 'react'

export default class Parent extends Component{

    state={carName:"奔驰C36"}

    changeCar=()=>{
        this.setState({carName:'迈巴赫'})
    }
    shouldComponentUpdate(nextProps,nextState){
        //nextProps,nextState:接下来要变化的目标props,目标state
        //this.props,this.state:目前的props和state
        if(this.state.carName===nextState.carName) return false
        else return true
    }
    render(){
        const {carName}=this.state
        return (
            <div>
                <h3>我是parent组件</h3>
                <span>我的车名字是:{this.state.carName}</span><br/>
                <button onClick={this.changeCar}>点我换车</button>
                <Child carName={carName}/>
            </div>
        )
    }
}

class Child extends Component{
    shouldComponentUpdate(nextProps,nextState){
    //nextProps,nextState:接下来要变化的目标props,目标state
    //this.props,this.state:目前的props和state
    if(this.props.carName===nextProps.carName) return false
    else return true}
    render(){
        return (
            <div>
                <h3>我是child组件</h3>
                <span>我接到的车是:{this.state.carName}</span>
            </div>
        )
    }
}

第二种方法是使用PureComponent:

import React,{PureComponent} from 'react'

export default class Parent extends PureComponent{

    state={carName:"奔驰C36"}

    changeCar=()=>{
        this.setState({carName:'迈巴赫'})
    }
    render(){
        const {carName}=this.state
        return (
            <div>
                <h3>我是parent组件</h3>
                <span>我的车名字是:{this.state.carName}</span><br/>
                <button onClick={this.changeCar}>点我换车</button>
                <Child carName={carName}/>
            </div>
        )
    }
}

class Child extends PureComponent{
    render(){
        return (
            <div>
                <h3>我是child组件</h3>
                <span>我接到的车是:{this.state.carName}</span>
            </div>
        )
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李喵喵爱豆豆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值