组件通信------context
简介:
组件通信有如下方式,本篇文章主要讲述context
1、父组件与子组件通信
(父传子就是属性)
1)父组件将自己的状态传递给子组件,子组件当作属性来接收,当父组件要更改自己状态的时候,子组件接收到的属性就会发生改变
2)父组件利用ref对子组件标记,通过调用子组件的方法已更改子组件的状态,也可以调用子组件的方法
2、子组件与父组件通信
(子传父就是写个函数往里面传)
1)父组件将自己的某个方法传递给子组件,在方法里可以任意操作,比如可以更改状态,子组件通过this.props接收到父组件的方法后调用
3、跨组件通信
在react没有类似vue中的事件总线来解决这个问题,我们只能借助它们共同的父级组件来实现,将非父子关系转换成多维度的父子关系。react提供了context api来实现跨组件通信。Reacct 16.3之后的context api较之前的好用
(react里面是没有状态管理工具的,如果想要使用状态管理工具只能使用第三方插件,所有react弄了一个context)
4、状态管理工具
context
类组件使用context、函数组件使用context
用法:
1、封装testContext.js
import {createContext} from 'react'
// 调用createContext之后赋给testContext
const testContext = createContext()
// 解构出两个对象 ,赋给testContext
const {Provider, Consumer} = testContext
// 暴漏出去
export {
testContext,
Provider,
Consumer
}
2、哪块需要哪块引入
import {Consumer,Provider,testContext} from './testContext'
在父组件处使用Provider组件,将值挂载在根上,举例在Provider写value属性传递hello
export default class componentName extends Component {
render() {
return (
<Provider value="hello">
hello
<ChildA></ChildA>
<ChildB></ChildB>
</Provider>
)
}
}
3、类组件使用context
定义静态属性并且将testContext赋给静态属性
通过this.context可直接获取到根上的“hello”字符串
class ChildA extends Component {
// 对于类组件通过这样的方法进行获取
// 将testContext赋给静态属性
static contextType = testContext
render() {
console.log(this, 'this')
return (
<div>
child a:{this.context}
</div>
)
}
}
4、函数组件使用context
与类组件使用方法不同,原因是函数组件不能写static这个变量,也没有this,context也没有
1)先写一个Consumer组件
2)写个花括号
3)花括号里面再写个函数
4)函数里面value的值就是根上定义的“hello字符串”
const ChildC = function(props) {
return (
<div>
Child c
<ChildD></ChildD>
<Consumer>
{
(value) => {
console.log(value, 'value')
return <div>{value}</div>
}
}
</Consumer>
</div>
)
}
全部代码
testContext.js
import {createContext} from 'react'
// 调用createContext之后赋给testContext
const testContext = createContext()
// 解构出两个对象 ,赋给testContext
const {Provider, Consumer} = testContext
// 暴漏出去
export {
testContext,
Provider,
Consumer
}
context.js
import React, { Component } from 'react'
import {Consumer,Provider,testContext} from './testContext'
// 类组件A
class ChildA extends Component {
// 对于类组件通过这样的方法进行获取
// 将testContext赋给静态属性
static contextType = testContext
render() {
console.log(this, 'this')
return (
<div>
child a:{this.context}
</div>
)
}
}
// 类组件B
class ChildB extends Component {
render() {
return (
<div>
child b
<ChildC></ChildC>
</div>
)
}
}
// 函数组件C
const ChildC = function(props) {
return (
<div>
Child c
<ChildD></ChildD>
{/* 函数组件不能写static这个变量,也没有this,context也没有 */}
{/* 在函数组件中的用法 */}
{/* 1、先写一个Consumer组件 */}
{/* 2、写个花括号 */}
{/* 3、花括号里面再写个函数 */}
{/* 4、函数里面value的值就是根上定义的“hello字符串” */}
<Consumer>
{
(value) => {
console.log(value, 'value')
return <div>{value}</div>
}
}
</Consumer>
</div>
)
}
// 函数组件D
const ChildD = function(props) {
return (
<div>Child d</div>
)
}
export default class componentName extends Component {
render() {
return (
<Provider value="hello">
hello
<ChildA></ChildA>
<ChildB></ChildB>
</Provider>
)
}
}