9.React Context 上下文
1.Context
在 react 中,我们会遇到这么一个情况,如果爷爷想传东西给孙子,那么就需要这么做:爷爷 传给 父亲,父亲再传给自己的儿子。
如果层级嵌套的特别深,怎么传递呢?这时候就要引出我们今天的知识点 context 上下文,可以通过设置上下文,让参数容易读取,不需要层层传递。
// 在实际项目中。父传子 和 redux 使用比较多,context 的功能间于两者之间,往往被忽略
下面就一个简单的例子来说明:
2.实例解析
2.1 jsx 版本:
App 是父组件,创建上下文
Children 和 Grandson 展示了两种获取上下文的方式
这是目录结构:
└─component
App.jsx
Children.jsx
Grandson.jsx
App.js:
import React from "react";
import Children from "./Children";
// 创建一个 theme Context,
export const Context = React.createContext("默认名称");
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
color: "red"
}
}
render() {
return (
<div>
<h1>APP</h1>
<Context.Provider value={this.state.color}>
<Children />
</Context.Provider>
</div>
)
}
}
Children.js:
第一种获取上下文的方式
import React from "react";
import { Context } from "./App";// 引入父组件的Consumer容器
import Grandson from "./Grandson";
export default class Children extends React.Component {
constructor(props) {
super(props);
this.state = {};
//不写在这里的话初始化的时候不会获取到传递的context
Children.contextType = Context;
}
render() {
return (
<div>
<h2 style={{ color: this.context }}>儿子</h2>
<Grandson />
</div>
)
}
}
Gandson.js:
第二种获取上下文的方式
import React from "react";
import { Context } from "./App";// 引入父组件的Consumer容器
export default class Grandson extends React.Component {
render() {
return (
<Context.Consumer>
{
(params) => {
return (
<div style={{ color: params }}>孙子</div>
)
}
}
</Context.Consumer>
)
}
}
2.2 tsx 版本:
这是目录结构: 同上
App.js:
import React, { createContext, Context } from "react"; import Children from "./Children" type propsType = {}; type stateType = { userInfo: any, }; //这里要导出这个上下文,下面的子孙组件哪个用到context的东西哪个就引入一下 export const InfoContext: Context<any> = createContext({ name: "", age: 0, }); class App extends React.Component<propsType, stateType> { constructor(props) { super(props); this.state = { userInfo: { name: "test", age: -1, }, }; } handleClick = () => { let info = { name: "ls", age: 20, }; this.setState({ userInfo: info, }); }; render() { return ( <InfoContext.Provider value={this.state.userInfo}> <button onClick={() => this.handleClick()}>传递</button> <Children></Children> </InfoContext.Provider> ); } } export default App;
Children.js:
没有获取上下文
import React from "react"; import Grandson from "./Grandson"; type propsType = {}; type stateType = {}; class Children extends React.Component<propsType, stateType> { constructor(props) { super(props); this.state = {}; } render() { return ( <div> 中间的子组件 <Grandson></Grandson> </div> ); } } export default Children;
Gandson.js:
import React from "react"; import { InfoContext } from './App'//引入上下文 type propsType = {}; type stateType = {}; class Grandson extends React.Component<propsType, stateType> { constructor(props) { super(props); this.state = {}; //不写在这里的话初始化的时候不会获取到传递的context Grandson.contextType = InfoContext; } render() { return ( <div> 最下面的孙子组件 <br /> <label>姓名:{this.context.name}</label> <br /> <label>年龄:{this.context.age}</label> </div> ); } } export default Grandson;