React 利用Context实现组件通信

本文是自己学习useContext的笔记。

1. 两组件通信

React 中,父子组件需要通信时,父组件可以将参数写在props中传递给子组件,实现父组件向子组件通信;父组件还可以传递一个函数给子组件,子组件调用这个函数,实现子组件向父组件的通信。这就完成了父子组件的相互通信。

但当组件嵌套关系复杂的时候,如下图所示,A组件下有B组件和C组件,B组件下有D组件,C组件下有E组件。

当需要在A组件和D组件之间通信时,也可以采取上述的方法,A通过props一层一层传递参数到D组件,D组件再调用函数,一层一层返回到A组件。

2. Context

但当组件嵌套关系更复杂时,这样的方式极其繁琐,且不易维护。这里介绍一种使用Context实现组件通信的方式。

Context 提供了一个无需为每层组件手动添加 props,就能在组件树间进行数据传递的方法。

使用Context,可以避免通过中间组件传递props。有的时候在组件树中很多不同层级的组件需要访问同一批数据Context能让你将这些数据向组件树下所有的组件进行广播,所有的组件都能访问到这些数据,也能访问到后续的数据更新。

3. useContext 实践

首先实现上述关系的组件:

要实现的效果为,E组件中点击add,会增加计数值。点击D组件的clear按钮,会对E组件的计数值进行清零

A组件中,需要从react中导入createContext方法,在组件外部创建Context对象,并导出。同时,需要用<MyContext.Provider></MyContext.Provider>进行包裹,其中,MyContext是自定义的名称。数据对象放在<MyContext.Provider>value中。这样,被包裹的所有组件,都能直接拿到这两个参数了。

import { createContext, useState } from 'react';
import B from './B';
import C from './C';
import './index.css';

// 在组件外部创建Context对象,并导出
export const MyContext = createContext();

const A = () => {
    const [count, setCount] = useState(0);
    return (
        // 数据对象放在value中,向下传递
        <MyContext.Provider value={{ count, setCount }}>
            A组件
            <B />
            <C />
        </MyContext.Provider>
    );
};

export default A;

E组件需要从A中引入创建的context对象MyContext,并使用useContext方法,从MyContext中拿到其中的参数。

// 引入创建的context
import { MyContext } from './A';
import { useContext } from 'react';

const E = () => {
    // 拿到两个参数
    const { count, setCount } = useContext(MyContext);

    return (
        <div>
            我是E, 计数值:{count}
            <button onClick={() => setCount(count => count + 1)}>add</button>
        </div>
    );
};

export default E;

D组件也需要从A中引入创建的context对象MyContext,使用useContext方法,拿到setCount方法。

// 引入创建的context
import { MyContext } from './A';
import { useContext } from 'react';

const D = () => {
    // 拿到参数
    const { setCount } = useContext(MyContext);

    return (
        <div>
            我是D
            <button onClick={() => setCount(0)}>clear</button>
        </div>
    );
};

export default D;

这样,E组件和D组件使用的是同一批数据,也能访问到这些数据的更新,实现了跨组件通信。

4. 集中式管理 Context 对象

如果一个项目中,多处使用context,会造成代码结构不清晰,不便于维护。这时可以将所有创建context的代码,放入到专门的文件中,进行集中管理,需要用到的地方,都从此文件引入即可。

例如,将创建的所有Context对象放入contextManager.js中,并导出:

// contextManager.js

import { createContext } from 'react';

export const MyContext = createContext();

// 定义的其他context
export const MyContext2 = createContext();
export const MyContext3 = createContext();
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

火星飞鸟

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

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

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

打赏作者

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

抵扣说明:

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

余额充值