react context传值

三种传值方法

  1. 类组件的 static contextType =
  2. 函数组件的useContext
  3. Consumer 函数组件,类组件都可以

static contextType 类组件使用

创建context

//creatContext.js
import React from 'react'

export const NameContext = React.createContext();
export const AgeContext = React.createContext();

导入创建的context 并使用provider嵌套需要消费的组件

//主要显示的组件

import React, { Component } from 'react'
import { NameContext, AgeContext } from './creatContext'
import ClassChild from './classChild'

export default class index extends Component {

    state = {
        name: "张三",
        age: 18
    }
    render() {
        const { name, age } = this.state;
        return (
            <NameContext.Provider value={name}>
                <AgeContext.Provider value={age}>
                    <ClassChild />
                </AgeContext.Provider>
            </NameContext.Provider>
        )
    }
}

再导入创建的context 并使用静态类方法contextType接收

//classChild.js
import React, { Component } from 'react'
import { NameContext, AgeContext } from './creatContext'
export default class child extends Component {
    static contextType = NameContext
    static contextType = AgeContext

    render() {
        console.log(this.context)
        return (
            <div>
                
            </div>
        )
    }
}

这里使用两个context接收是因为 class组件静态方法只可接收一个context,当然或许回想传一个对象其他值往里面塞 但是这个差异一定要知道

useContext 函数组件使用

同上引入创建context文件夹

主文件

import React, { Component } from 'react'
import { NameContext, AgeContext } from './creatContext'
import FunChild from './funChild'

export default class index extends Component {

    state = {
        name: "张三",
        age: 18
    }
    render() {
        const { name, age } = this.state;
        return (
            <NameContext.Provider value={name}>
                <AgeContext.Provider value={age}>
                    <FunChild />
                </AgeContext.Provider>
            </NameContext.Provider>
        )
    }
}

子组件


import { useContext } from 'react'

import { NameContext, AgeContext } from './creatContext'


export default function FunChild() {

    const name = useContext(NameContext)
    const age = useContext(AgeContext)

    return (
        <div>
            {name}
            {age}
        </div>
    )
}

在函数组件中使用usecontext接收毫无疑问是可以接收两个的 因为我们可以用两个api去接收

Consumer 都可用

Consumer是类组件 函数组件都可以使用的 因为是createContext中的api
主组件:

import React, { Component } from 'react'
import { NameContext, AgeContext } from './creatContext'
import ClassChild from './classChild'
import FunChild from './funChild'

export default class index extends Component {

    state = {
        name: "张三",
        age: 18
    }
    render() {
        const { name, age } = this.state;
        return (
            <NameContext.Provider value={name}>
                <AgeContext.Provider value={age}>
                    <FunChild />
                    <h1>类组件↓</h1>
                    <ClassChild />
                </AgeContext.Provider>
            </NameContext.Provider>
        )
    }
}
类组件中的表现

import React, { Component } from 'react'
import { NameContext, AgeContext } from './creatContext'
export default class child extends Component {

    render() {
        return (
            <div>
                <NameContext.Consumer>
                    {data => { return <p>类组件接收的name:{data}</p> }}

                </NameContext.Consumer>

                <AgeContext.Consumer>
                    {data => { return <p>类组件接收的age:{data}</p> }}
                </AgeContext.Consumer>
                <h3>下方是类组件中嵌套尝试</h3>

                <NameContext.Consumer>
                    {name => {
                        return <div>
                            我的名字叫{name}
                            <AgeContext.Consumer>
                                {age => { return <p>我的年龄是{age}</p> }}
                            </AgeContext.Consumer>
                        </div>
                    }}

                </NameContext.Consumer>

            </div>
        )
    }
}
函数组件
import React from 'react'
import { NameContext, AgeContext } from './creatContext'

export default function FunChild() {

    return (
        <div>
            <NameContext.Consumer>
                {name => { return <p>函数组件中的name: {name}</p> }}
            </NameContext.Consumer>
            <AgeContext.Consumer>
                {age => { return <p>函数组件中的age: {age}</p> }}
            </AgeContext.Consumer>

            <h1>函数组件中的嵌套尝试↓</h1>
            
            <NameContext.Consumer>
                {name => {
                    return <div>
                        我的名字叫{name}
                        <AgeContext.Consumer>
                            {age => { return <p>我的年龄是{age}</p> }}
                        </AgeContext.Consumer>
                    </div>
                }}

            </NameContext.Consumer>
        </div>
    )
}

效果图

react context传值_第1张图片

需要注意事项

context会使用参考标志来决定何时进行渲染,这里有一个陷阱 如果是引用数据类型
例:

//传递的值是对象类型

<AgeContext.Provider value={{name: '对象'}}>
                    <FunChild />
                    <h1>类组件↓</h1>
                    <ClassChild />
</AgeContext.Provider>

这样在每次进行组件更新时对比原数据和新数据是否有差异 会做一个这样对比的操作

{name: '对象'} === {name: '对象'}

没有变量保存地址 引用地址是不同的 这样每次其他组件更新 这个provider下的组件都会判定数据不同 导致不必要的更新

这时候需要把数据提升到父组件中保存 改数据的引用地址 就比如存在state中

你可能感兴趣的:(react,javascript)