React组件通信-非父子组件间的通信
文章目录
- React非父子组件通信
- 小知识点的补充
- Context应用场景
- Context相关API
- Context使用流程
React非父子组件通信
在React中, 非父子组件传递是通过一个API: Context
小知识点的补充
在讲非父子组件传递之前, 我这边顺便补充一个小的知识点:Spread Attributes
例如现在有一个对象info, 将info的信息传入到子组件中, 大家可能都会这样传进去
export class App extends Component {constructor() {super()this.state = {info: {name: "chenyq",age: 18,height: 1.88}}}render() {const { info } = this.statereturn (<div><Home name={info.name} age={info.age} height={info.height}/></div>)}
}
其实有一种展开语法可以帮助我们传入一个对象
export class App extends Component {constructor() {super()this.state = {info: {name: "chenyq",age: 18,height: 1.88}}}render() {const { info } = this.statereturn (<div>{/* 展开语法传入一个对象 */}<Home {...info}/></div>)}
获取数据的方式和我们普通传入数据的方式一样
export class Home extends Component {render() {const { name, age, height } = this.propsreturn (<div><h2>名字: {name} 年龄: {age} 身高: {height}</h2></div>)}
}
Context应用场景
非父子组件数据的共享:
在开发中,比较常见的数据传递方式是通过props属性自上而下(由父到子)进行传递。
但是对于有一些场景:比如一些数据需要在多个组件中进行共享(地区偏好、UI主题、用户登录状态、用户信息等)。
如果我们在顶层的App中定义这些信息,之后一层层传递下去,那么对于一些中间层不需要数据的组件来说,是一种冗余的操作。
但是,如果层级更多的话,一层层传递是非常麻烦,并且代码是非常冗余的:
React提供了一个API:Context;
Context 提供了一种在组件之间共享此类值的方式,而不必显式地通过组件树的逐层传递 props;
Context 设计目的是为了共享那些对于一个组件树而言是“全局”的数据,例如当前认证的用户、主题或首选语言;
Context相关API
React.createContext
创建一个需要共享的Context对象:
如果一个组件订阅了Context,那么这个组件会从离自身最近的那个匹配的 Provider 中读取到当前的context值;
defaultValue是组件在顶层查找过程中没有找到对应的Provider,那么就使用默认值
const MyContext = React.createContext({name: "默认名称", age: 1})
Context.Provider
每个 Context 对象都会返回一个 Provider React 组件,它允许消费组件订阅 context 的变化:
Provider 接收一个 value 属性,传递给消费组件;
一个 Provider 可以和多个消费组件有对应关系;
多个 Provider 也可以嵌套使用,里层的会覆盖外层的数据;
当 Provider 的 value 值发生变化时,它内部的所有消费组件都会重新渲染;
<MyContext.Provider value={{name: "chenya", age: 18}}><Home {...info}/>
</MyContext.Provider>
Class.contextType
挂载在类组件上的 contextType 属性会被重赋值为一个由 React.createContext() 创建的 Context 对象:
这能让你使用 this.context 来消费最近 Context 上的那个值;
你可以在任何生命周期中访问到它,包括 render 函数中;
HomeHeader.contextType = MyContext
Context.Consumer
这里,React 组件也可以订阅到 context 变更。这能让你在 函数式组件 中完成订阅 context。
这里需要 函数作为子元素(function as child)这种做法;
这个函数接收当前的 context 值,返回一个 React 节点;
<MyContext.Consumer>{value => {return <h2>名字: {value.name} 年龄: {value.age}</h2>}}
</MyContext.Consumer>
Context使用流程
例如我们现在有一个爷爷组件App.jsx, 现在需要向孙子组件HomeHeader.jsx传递数据
第一步操作: 创建一个Context, 由于这个Context会在爷爷组件和孙子组件中都用到, 所以我们单独创建一个context文件夹, 在文件夹的my-context.js
文件中
这个文件分别导入要传数据的组件和要接受数据的组件
import React from 'react'const MyContext = React.createContext({name: "默认名称", age: 1})export default MyContext
第二步操作: 在爷爷组件中, 通过MyContext中Provider中value属性为后代提供数据
// 爷爷组件import MyContext from './context/my-context'export class App extends Component {render() {const { info } = this.statereturn (<div><MyContext.Provider value={{name: "chenya", age: 18}}><Home {...info}/></MyContext.Provider></div>)}
}export default App
第三步操作: 在要接受数据的孙子组件中, 设置组件的contextType为哪一个Context, 因为可能会有多个Context, 所以需要明确指定是哪一个
// 孙子组件import React, { Component } from 'react'
import MyContext from './context/my-context'export class HomeHeader extends Component {render() {return (<div>hhh</div>)}
}HomeHeader.contextType = MyContextexport default HomeHeader
第四步操作: 获取数据, 并且使用数据
有两种方法可以获取, 如果该孙子组件只有使用一个Context的数据, 那么可以直接在
this.context
中获取数据
import React, { Component } from 'react'
import MyContext from './context/my-context'export class HomeHeader extends Component {render() {// 直接在this.context中获取const { name, age } = this.contextreturn (<div><h2>名字: {name} 年龄: {age}</h2></div>)}
}HomeHeader.contextType = MyContextexport default HomeHeader
如果该孙子组件已经通过
HomeHeader.contextType = 其他Context
这个API, 绑定了其他的Context, 那么就需要如下方式获取
import React, { Component } from 'react'
import MyContext from './context/my-context'export class HomeHeader extends Component {render() {return (<div><MyContext.Consumer>{value => {return <h2>名字: {value.name} 年龄: {value.age}</h2>}}</MyContext.Consumer></div>)}
}HomeHeader.contextType = MyContextexport default HomeHeader
- 什么时候使用Context.Consumer呢?
当使用value的组件是一个
函数式组件
时;
import ThemeContext from "./context/theme-context"function HomeBanner() {return <div>{/* 函数式组件中使用Context共享的数据 */}<ThemeContext.Consumer>{value => {return <h2> Banner theme:{value.color}</h2>}}</ThemeContext.Consumer></div>
}export default HomeBanner
当组件中需要使用多个Context时;
React组件通信-非父子组件间的通信相关推荐
- Vue.js组件-组件通信-非父子组件传值以及其他通信方式
非父子组件传值 非父子组件指的是兄弟组件或完全无关的两个组件 兄弟组件 兄弟组件可以通过父组件进行数据中转,简单来讲,A是父组件,BC是两个兄弟组,那么我们可以先B传给A,再A传给C.示例如图: Ev ...
- 父子组建传值_浅谈Vue父子组件和非父子组件传值问题
本文介绍了浅谈Vue父子组件和非父子组件传值问题,分享给大家,具体如下: 1.如何创建组件 1.新建一个组件,如:在goods文件夹下新建goodsList.vue goodsList组件 expor ...
- vue2.0父子组件以及非父子组件如何通信
1.父组件传递数据给子组件 父组件数据如何传递给子组件呢?可以通过props属性来实现 父组件: <parent><child :child-msg="msg"& ...
- vue父子组件及非父子组件之间的传值
一.父组件向子组件传值 在vue中通常使用props向子组件传递数据 1.创建子组件,在src/components/文件夹下新建一个Child.vue 2.Child.vue的中创建props,然后 ...
- Vue之非父子组件通信
Vue之非父子组件通信 非父子组件传值方法: 1:在model中新建一个js文件 引入Vue 实例化Vue 最后暴露相关实例 // 引入vue import Vue from 'vue' // 创建 ...
- Vue组件化开发--组件通信方式-父传子、子传父、非父子组件传值
一.概述 以脚手架搭建的Vue项目为笔记背景. 如果将所有的代码逻辑全部放到一个组件中,代码是非常的臃肿和难以维护的. 并且在真实开发中,可能会有更多的内容和代码逻辑,对于扩展性和可维护性来说都是非常 ...
- angular框架如何实现父子组件传值、非父子组件传值
文章目录 1.理解父子组件.非父子组件 2.父组件给子组件传值- -@input 3.父组件通过@ViewChild主动获取子组件的数据和方法 4.非父子组件如何传递数据 1.理解父子组件.非父子组件 ...
- [react] react非父子组件如何通信?
[react] react非父子组件如何通信? redux context 个人简介 我是歌谣,欢迎和大家一起交流前后端知识.放弃很容易, 但坚持一定很酷.欢迎大家一起讨论 主目录 与歌谣一起通关前端 ...
- vue 2 使用 Bus.js 实现兄弟 (非父子) 组件通信 简单案例
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. vue2中废弃了$dispatch和$broadcast广播和分发事件的方法.父子组件中可以用pro ...
最新文章
- 超级全面的 SpringBoot 注解介绍,每一个用途都应该清晰
- Revit二次开发示例:DeleteDimensions
- 作业帮电脑版在线使用_在线K12赛道六虎争霸:猿辅导、作业帮又宣布新一轮融资...
- boost::gil::ImageConcept用法的测试程序
- yuzu模拟器linux,Yuzu Early Acces
- Java命令学习系列(一)——Jps
- java datainputstream_Java中DataInputStream的用法
- 微型计算机系统的工作过程是不断地,微型计算机原理及应用基本学习要求2017-2(1)...
- 【Algorithm】逆序数的分治求解
- Python接口自动化实战(第二阶段)- unittest框架
- c语言画圆登录窗口,C语言画圆问题。怎么跳过画图界面直接出来了?
- MySQL如何建索引以及利用索引优化ORDER BY排序语句
- 最新中国一二三四五线城市排名出炉!去这些城市买房准没错!
- 极客大学产品经理训练营:数据分析与用户数据 第17课总结
- 老徐WEB:js入门学习 - javascript变量的数据类型
- Q3手机银行运营报告:直销银行江湖再起波澜,数字员工助力手机银行活跃度提升
- 59. 建立正序链表
- 利用python的turtle库绘制玫瑰的步骤_用python turtle画玫瑰
- python:水果与设计模式-原型模式
- 新手入门PS人像磨皮教程