组件跨层级通信-Context
在一个典型的React项目中,数据是通过props属性自上而下的(由父及子)进行传递,但是这种做法对于某些类型的属性而言是极其繁琐的(例如:地区偏好,UI主题),这些属性是应用程序中许多组件都需要的。Context提供了一种在组件之间共享此类值的方式,而不必显示地通过组件树的逐层传递props
具体使用方法
- 首先下载React脚手架,并搭建好目录
- 第一步在src文件夹下创建utils文件夹,并创建ThemeContext.js文件,以及其他组件
3.在ThemeContext文件下书写一下代码(用来创建公用的Context)
import React from "react";
//创建context 农民种菜 如果没有匹配到Provider取默认值
export const ThemeContext = React.createContext({ themeColor: "pink" });
//接收者 批发商批发菜
export const ThemeProvider = ThemeContext.Provider;
//消费者 吃菜
export const ThemeConsumer = ThemeContext.Consumer;
4.在App文件里书写爷爷组件App,并在爷爷组件引入父亲组件List
import React, { Component } from "react";
import { ThemeProvider } from "../src/utils/ThemeContext";
import ContextTypePage from "../src/components/List";
//使用Context 步骤
//1.创建createContext
//2.Provier 接收value,以保证又传下去的数据
//3.接收Consumer或者class.contextType
class ContextPage extends Component {
constructor(props) {
super(props);
this.state = {
theme: {
themeColor: "red",
},
};
}
render() {
const { theme } = this.state;
return (
<div>
<h3>ContextPage</h3>
<ThemeProvider value={theme}>
{/* 只能订阅一个context */}
<ContextTypePage />
</ThemeProvider>
</div>
);
}
}
export default ContextPage;
5.在List文件里书写父亲组件List,并在爷爷组件引入孙子组件Item
import React, { Component } from "react";
import Item from "./Item";
export default class List extends Component {
render() {
return (
<div>
<Item></Item>
</div>
);
}
}
6.孙子组件Item,方法一:使用static子组件进行数据的展示和渲染
import React, { Component } from "react";
import { ThemeContext } from "../utils/ThemeContext";
export default class Item extends Component {
//只能订阅一个context,并且是类组件
static contextType = ThemeContext;
render() {
const { themeColor } = this.context;
//this.context 在任何声明周期都可以访问到
return (
<div>
<h3 className={themeColor}>Item{themeColor}</h3>
</div>
);
}
}
7.孙子组件Item,方法二:使用Consumer子组件进行数据的展示和渲染
import React from "react";
import { ThemeConsumer } from "../utils/ThemeContext";
export default function Item(props) {
return (
<div className="border">
<h3>Item</h3>
<ThemeConsumer>
{(ctx) => <div className={ctx.themeColor}>Item{ctx.themeColor}</div>}
</ThemeConsumer>
</div>
);
}
这样就实现了跨级传参
总结
1.创建context对象, 如果没有匹配到Provider取默认值
export const ThemeContext = React.createContext({ themeColor: "pink" });
2.Provier 接收value,以保证又传下去的数据
<ThemeProvider value={this.state.theme}></ThemeProvider>
3.接收Consumer或者class 的static
使用Consumer
import React from "react";
import { ThemeConsumer } from "../utils/ThemeContext";
export default function Item(props) {
return (
<div className="border">
<h3>Item</h3>
<ThemeConsumer>
{(ctx) => <div className={ctx.themeColor}>Item{ctx.themeColor}</div>}
</ThemeConsumer>
</div>
);
}
使用static
import React, { Component } from "react";
import { ThemeContext } from "../utils/ThemeContext";
export default class Item extends Component {
//只能订阅一个context,并且是类组件
static contextType = ThemeContext;
render() {
const { themeColor } = this.context;
//this.context 在任何声明周期都可以访问到
return (
<div>
<h3 className={themeColor}>Item{themeColor}</h3>
</div>
);
}
}
官网文档地址:https://react.docschina.org/docs/context.html#contextprovider