Skip to content

childContext & createContext #4

@CyfforPro

Description

@CyfforPro
import React from "react";
import PropTypes from "prop-types";

//#region 方式一: childContext
class GrandSon extends React.Component {
  render() {
    return <div>{this.context.value}</div>;
  }
}

// childContext的消费者必须定义这个,可以理解为辅助判断消费者需要消费的到底是哪个值
GrandSon.contextTypes = {
  value: PropTypes.string
};

// fc消费childContext方式,参数一为props, 参数二为context
function GrandSonFn(props, context) {
  return <div>{context.value}</div>;
}

// 同样要定义contextTypes
GrandSonFn.contextTypes = {
  value: PropTypes.string
};
//#endregion

//#region 方式二: createContext
const createdContext = React.createContext();

class GrandSon2 extends React.Component {
  // 跟childContext很像,但是注意这里的this.context就是Provider的value了,不需要再this.context.value
  static contextType = createdContext;
  render() {
    return <div>{this.context}</div>;
  }
}

function GrandSon2Fn() {
  // fc消费createContext方式,使用Consumer
  return (
    <createdContext.Consumer>
      {value => <div>{value}</div>}
    </createdContext.Consumer>
  );
}
//#endregion

class Son extends React.Component {
  render() {
    return (
      <>
        <GrandSon />
        <GrandSonFn />
        <GrandSon2 />
        <GrandSon2Fn />
      </>
    );
  }
}

class Parent extends React.Component {
  // childContext的生产者必须提供getChildContext和childContextTypes
  // 这个getChildContext会在Parent更新时自动调用,从而让子组件能拿到最新的value
  // 但是若Parent与GrandSon中间有组件禁用更新了(shouldComponentUpdate),GrandSon的context也无法更新了
  getChildContext() {
    return { value: "childContext" };
  }

  render() {
    return (
      <createdContext.Provider value="createContext">
        <Son />
      </createdContext.Provider>
    );
  }
}

// childContext的生产者必须提供getChildContext和childContextTypes
Parent.childContextTypes = {
  value: PropTypes.string
};

export default Parent;

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions