学习记录——react的跨级传值React.createContext

本文深入解析React中跨组件传值的实现方法,重点介绍createContext API的使用,包括Provider和Consumer组件的作用及示例代码,展示了如何在祖先组件与后代组件间高效传递数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

React里面的api:
React.createContext (通过这个api完成跨级传值)里面有如下:
Provider 外层 生产数据 (数据的生产者)
Consumer 内层 消费数据 (数据的消费者)
这两个都是组件
作用:方便祖先组件与后代组件传值
也就是通过React.createContext()创建一个Context对象,这个Context对象包含两个组件< Provider />和< Consumer />

示例代码
views里面新建:
Home.js父组件
Son.js子组件和Grandson.js孙子辈组件
它们是互相嵌套的关系
Home里包含Son子组件
Son组件包含Grandson组件

Home.js:

import React, { Component } from 'react'
import Son from './Son'

export default class Home extends Component {
    render() {
        return (
            <div>
                <Son/>
            </div>
        )
    }
}

Son.js:

import React, { Component } from 'react'
import Grandson from './Grandson'

export default class Son extends Component {
    render() {
        return (
            <div>
                Son
                <Grandson/>
            </div>
        )
    }
}

Grandson.js:

import React, { Component } from 'react'

export default class Grandson extends Component {
    render() {
        return (
            <div>
                Grandson
            </div>
        )
    }
}

先打开页面查看是否能正常显示内容:
在这里插入图片描述

然后在src文件夹下创建utils文件夹,里面新建GrandParentContext.js文件
在这里插入图片描述
现在的情况是,我们有一个父组件Home,在这个父组件里有一个Son儿子组件。
而在Son儿子组件中,又包含了Grandson孙子组件。
那么如果我们想将父组件的值,传递给孙子组件的话,就是跨组件传值,就要用到createContext这个方法了。

回到Home.js里:
将创建的GrandParentContext引入 并模拟一个想要传到孙子组件的数据
在这里插入图片描述

import React, { Component } from 'react'
import Son from './Son'
import GrandParentContext from '../utils/GrandParentContext'

export default class Home extends Component {
    state = {
        obj: {
            name: '这是一个名字',
            age: 12
        }
    }
    render() {
        return (
            //要使用Provider将子组件包裹起来 值传到子组件,必须使用value
            <GrandParentContext.Provider value={this.state.obj}>
                <div>
                    <Son />
                </div>
            </GrandParentContext.Provider>
        )
    }
}

Provider有一个固定的value属性,传递给消费组件。当value值发生变化时,它内部的所有消费组件都会重新渲染

最后到Grandson组件:
在这里插入图片描述
打开页面查看:
在这里插入图片描述
上面这个使用static是向上级找组件,用它就不用再使用Consumer这个组件了
如果想使用这个组件,可以这么写:

import React, { Component } from 'react'
import GrandParentContext from '../utils/GrandParentContext'

export default class Grandson extends Component {

    //想上级找Provider
    //static contextType = GrandParentContext

    render() {
        return (
            <div>
                Grandson
                {/* <h3>姓名:{this.context.name}</h3>
                <h3>年龄{this.context.age}</h3> */}

                
                <GrandParentContext.Consumer>
                    {
                        (store) => {
                            return <div>
                                <h3>姓名:{store.name}</h3>
                                <h3>姓名:{store.age}</h3>
                            </div>
                        }
                    }
                </GrandParentContext.Consumer>
            </div>
        )
    }
}

总结

  1. 单独的文件中创建一个Context对象
    在这里插入图片描述
  2. 使用Provider进行传值(用于上层组件)
    在这里插入图片描述
  3. 内层组件接收值(this.context)
    在这里插入图片描述

内层组件向外层组件传值(子传父)

比如在Grandson这个里层组件里有个button,当点击时,会传一个值给外层组件Home

首先在最外层Home.js里:定义一个回调
在这里插入图片描述
然后到Son.js里:只需要将从父组件传过来的方法再传给它的子组件Grandson

import React, { Component } from 'react'
import Grandson from './Grandson'

export default class Son extends Component {
    render() {
        return (
            <div>
                Son
                <Grandson btnClick={this.props.btnClick}/>
            </div>
        )
    }
}

接着到Grandson.js里:将传过来的方法执行

import React, { Component } from 'react'
import GrandParentContext from '../utils/GrandParentContext'

export default class Grandson extends Component {

    //想上级找Provider
    static contextType = GrandParentContext

    render() {
        return (
            <div>
                Grandson
                <h3>姓名:{this.context.name}</h3>
                <h3>年龄{this.context.age}</h3>

                <button onClick={()=>{
                    this.props.btnClick('我是Grandson组件传过去的值')
                }}>点击传递到外层组件</button>

                {/* <GrandParentContext.Consumer>
                    {
                        (store) => {
                            return <div>
                                <h3>姓名:{store.name}</h3>
                                <h3>姓名:{store.age}</h3>
                            </div>
                        }
                    }
                </GrandParentContext.Consumer> */}
            </div>
        )
    }
}

这也就是相当于,把值先传到Son里面,再传到Home里
打开页面点击按钮查看:
在这里插入图片描述
注意
外层组件的createContext()必须和内层组件的createContext是同一个对象

### React TypeScript 中的组件通信 在React应用中,尤其是当涉及到TypeScript时,有多种方法可以在不同层次的组件间递数据。下面介绍几种常见的技术。 #### 使用回调函数进行自底向上通讯 对于从子代向祖先组件递信息的情况,可以采用回调函数的方式。先定义一个接口来描述预期的数据结构以及任何必要的事件处理程序签名[^1]: ```typescript // 定义子组件接受来自父的属性类型 interface ChildProps { onValueChange: (value: string) => void; } ``` 接着,在子组件内部调用此`onValueChange`函数以通知其上组件发生了变化。而父组件则负责提供具体的实现逻辑并响应这些更改。 #### 利用Context API 实现全局状态管理 如果应用程序中有多个地方都需要访问相同的状态,则推荐使用 Context API 来共享该状态。通过这种方式不仅可以简化 props 的层层钻取问题,而且还可以更好地支持大型复杂的应用场景[^3]。 首先创建上下文对象: ```javascript import * as React from 'react'; const MyContext = React.createContext<{ count: number; updateCount(value: number): void }>({ count: 0, updateCount: () => {}, }); ``` 然后利用 `useReducer` 或者简单的 state hook 创建 provider 组件包裹住需要获取 context 的部分,并向下播最新的给 consumer 子树中的所有后代节点。 最后,在消费端可以直接读取当前环境下的配置项或是触发相应的动作修改它。 #### Redux Store 集中式存储解决方案 除了上述两种方案外,还有更强大的工具比如Redux可以帮助开发者构建可预测性的UI层架构。借助于专门设计用于处理异步操作、副作用等问题的功能库(如redux-thunk),即使面对非常复杂的业务需求也能轻松应对[^2]。 不过得注意的是引入额外依赖可能会增加项目的维护成本和技术栈宽度,因此应当权衡利弊后再做决定。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值