(一)React之Context上下文

写在前面:本文适合有一定react基础的小伙伴,一些基础性的描述这里就不写了,官网也有,本文就是提炼一些主要内容,帮助你更好使用。有不同意见的记得评论区留下你的足迹哦,大家一起学习进步吧!

一、何时使用Context?

官网:Context 设计目的是为了共享那些对于一个组件树而言是“全局”的数据。

我:有数据被好几个组件都共用,但是不想从父组件一级一级通过props往下
传。如果组件嵌套太多层,还可能传错了,hhh。

二、使用Context前的考虑?

由于每个组件都可以通过单独的context方式去获取数据,而不是从外部传入通过props接收,这会导致组件的复用性变差。

三、如何使用Context?

1)创建一个context对象;
2)提供一个跨层级传递的数据 Provider(提供者);
3)在受用组件中使用一个接受对象 Consumer(消费者)。

还是通过具体代码示例来了解一下吧,真•具体•代码 如下:

第一步:创建一个父组件Home.jsx和一个子组件Son.jsx

import React, { Component } from 'react';
import Son from './Son'
export class Home extends Component {
    state={
        color:'red',
        size:30
    }
    render() {
        const {color,size}=this.state;
        const valueProps={
            size,color
        }
        return (
            <div>
                <p>Home </p>
                <Son {...valueProps}/> //常规传递参数的方式
            </div>
        )
    }
}

export default Home
import React, { Component } from 'react'
export class Son extends Component {
    render() {
        const {color,size}=this.props; //常规接收参数的方式
        return (
            <div >
                <p style={{color:color,fontSize:size}}>Son</p>
            </div>
        )
    }
}

export default Son

在这里插入图片描述
第二步:创建Context对象。(方便理解,我们把Context对象和返回的Provider React组件放到一个单独的context.js文件中)

import React from 'react';
export const DataContext=React.createContext();
export const DataProvider=DataContext.Provider;
export const DataConsumer=DataContext.Consumer;

所有的子组件需要包裹在provider中,并且接收一个value属性,即需要传递的数据。

第三步:改造父、子组件。

import React, { Component } from 'react';
import {DataProvider} from '../../utils/context';
import Son from './Son'

export class Home extends Component {
    state={
        color:'red',
        size:3
    }
    render() {
        const {color,size}=this.state;
        const valueProps={
            size,color
        }
        return (
            <div className='margin fontSize'>
                <p>home</p>
                <DataProvider value={valueProps}>
                    <Son/>
					//还有其他子组件 都放在这里
                </DataProvider>
            </div>
        )
    }
}
export default Home
//  Son.jsx组件:
import React, { Component } from 'react'
import {ThemeContext} from './context';

export class Son extends Component {
    // static contextType=ThemeContext;
    render() {
        const {color}=this.context;
        return (
            <div style={{color:color}}>
                Son
            </div>
        )
    }
}
Son.contextType=ThemeContext
export default Son

在这里插入图片描述
注意:挂载在组件上的contextType会被重赋值为一个Context对象,规定用this.context来访问那个值,可以在任何生命周期中使用它。

四、其他

1、如果子组件是个函数组件,写法是怎样呢?
让我们创建一个新的组件,就叫UsePage.jsx吧

import React  from 'react';

export default function UsePage (){
    return <div>
        usepage
    </div>
}

作为子组件引入到Son.jsx中,此时Son.jsx组件变成这样:

import React, { Component } from 'react'
import {DataContext} from '../../utils/context';
import UsePage from './UsePage'
export class Son extends Component {
// 指定 contextType 读取当前的 theme context。  
// React 会往上找到最近的 theme Provider,然后使用它的值。
    // static contextType=DataContext;   //写法一
    render() {
        const {color,size}=this.context;
        return (
            <div >
                <p style={{color:color,fontSize:size}}>Son</p>
   				<UsePage />  //在这引入组件
            </div>
        )
    }
}
Son.contextType=DataContext  //写法二

export default Son

此时页面显示:
在这里插入图片描述
注意:函数式页面需要用到react中的useContext方法,接受一个context作为参数。

import React,{useContext} from 'react';
import {DataContext} from '../../utils/context'
export default function UsePage (){
    const myCtx=useContext(DataContext)
    const {color,size}=myCtx;

    return <div style={{color:color,fontSize:size}}>
        usepage
    </div>
}

页面显示:
在这里插入图片描述
2、还可以在创建Context对象时候给个默认值。

import React from 'react';
export const DataContext=React.createContext({
    color:'green',
    size:14
});
export const DataProvider=DataContext.Provider;

此时,包裹在provider中的组件会接收父组件新传入的数据,
外层组件就会拿到默认值了。

import React, { Component } from 'react';
import {DataProvider} from '../../utils/context';
import Son from './Son'
import UsePage from './UsePage'
import './home.scss'
export class Home extends Component {
    state={
        color:'red',
        size:30
    }
    render() {
        const {color,size}=this.state;
        const valueProps={
            size,color
        }
        return (
            <div className='margin fontSize'>
                <p>home</p>
                <DataProvider value={valueProps}>
                    <Son/>
                </DataProvider>

                <UsePage />
            </div>
        )
    }
}

export default Home

在这里插入图片描述
3、使用多个Context
让我们再来给文字添加一个背景颜色。同样,创建一个新的Context对象。

export const BackContext=React.createContext({
    background:'yellow'
});
export const BackProvider=BackContext.Provider;
export const BackConsumer=BackContext.Consumer;

// Homes.jsx文件:
import React, { Component } from 'react';
import { DataProvider, BackProvider } from '../../utils/context';
import Son from './Son'
export class Home extends Component {
    state = {
        color: 'red',
        size: 30,
        background:'orange'
    }
    render() {
        const { color, size ,background} = this.state;
        const valueProps = {
            size, color
        }
        return (
            <div>
                <p>home</p>
                <BackProvider value={background}>
                    <DataProvider value={valueProps}>
                        <Son />
                    </DataProvider>
                </BackProvider>
            </div>
        )
    }
}
export default Home
// Son.jsx:
import React, { Component } from 'react'
import {  BackConsumer, DataConsumer } from '../../utils/context';

export class Son extends Component {
    render() {
        return (
            <BackConsumer>
                {
                     background=> (
                        <DataConsumer>
                            {
                                ({color,size}) => {
                                    return <p style={{ color: color, fontSize: size,backgroundColor:background }}>Son</p>
                                }
                            }
                        </DataConsumer>
                    )
                }
            </BackConsumer>

        )
    }
}
export default Son

usepage没有接受上级组件传递的color和size,使用了给的默认值
在这里插入图片描述
总结:
ContextType写法(static contextType=DataContext):
1、只能用在类组件中;
2、只能订阅单一的数据来源(如果需要多个,就使用Consumer);

useContext()写法(const ctx = React.useContext(ThemeContext)):
1、只能用在函数组件中;
2、可以订阅多个context对象

Consumer可以用在类组件和函数组件中,但是写法有点复杂了,多个需要一直嵌套下去。
消耗的性能很大,因为状态值存在父组件的state中,一旦更新一个数据,所有子组件都会更新。
所以现在可能redux用的比较多了(我自己是这样没错啦)。
有不足之处希望大家踊跃发言,接受一切批评、建议,为了美好的明天,冲!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值