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;