React Context使用

组件跨层级通信Context,类比Vue中的provider,Inject。

场景:一键换肤,切换地区

1,Context.js

API:

React.createContext

创建一个Context对象,当React渲染一个订阅了这个Context对象的组件,这个租金会从组件树中离自身最近的那个匹配的Provider中读取到当前的Context的值。

Context.Provider

Provider接受一个value属性,传递给消费组件,允许消费组件订阅context的变化。一个Provider可以和多个消费组件有对应关系。多个Provider也可以嵌套使用,里层的会覆盖外层的数据。

当Provider的value值发生变化时,它内部的所有消费组件都会重新渲染。Provider及其内部consumer组件都不受制于shouldComponentUpdate函数,因此当Consumer组件在其祖先组件退出更新的情况下也能更新。

Class.contextType

Context.Consumer

消费者

useContet

import React from "react";

export const ThemeContext = React.createContext({themeColor: "pink"});
export const ThemeProvider = ThemeContext.Provider; //提供者
export const ThemeConsumer = ThemeContext.Consumer; //消费者

export const UserContext = React.createContext();
export const UserProvider = UserContext.Provider;
export const UserConsumer = UserContext.Consumer;

2,ContextPage.js

ConsumerPage在<ThemeProvider>的服务区内,必须是Provider的子组件
import React, {Component} from "react";
import {ThemeProvider, UserProvider, UserContext} from "../Context";
import ConsumerPage from "./ConsumerPage";
import UseContextPage from "./UseContextPage";

export default class ContextPage extends Component {
  constructor(props) {
    super(props);
    this.state = {
      theme: {
        themeColor: "red"
      },
      user: {name: "xiaoming"}
    };
  }
  render() {
    const {theme, user} = this.state;
    return (
      <div>
        <h3>ContextPage</h3>
        <ThemeProvider value={theme}>
          <UserProvider value={user}>
            <ConsumerPage /> 
            <UseContextPage />
          </UserProvider>
        </ThemeProvider>
      </div>
    );
  }
}

3, ConsumerPage.js

接受一个参数返回一个组件

包在<ThemeConsumer>里面,代表是人家的用户

import React, {Component} from "react";
import {ThemeConsumer, UserConsumer} from "../Context";

export default class ConsumerPage extends Component {
  render() {
    return (
      <div>
        <h3>ConsumerPage</h3>
        <ThemeConsumer> 
          {themeContext => (
            <div className={themeContext.themeColor}>
              omg
              <UserConsumer>
                {userContext => <Child {...userContext} />}
              </UserConsumer>
            </div>
          )}
        </ThemeConsumer>
      </div>
    );
  }
}

function Child(props) {
  return <div>{props.name}</div>;
}

4,UseContextPage.js

import React, {useContext} from "react";
import {ThemeContext, UserContext} from "../Context";

export default function UseContextPage(props) {
  const {themeColor} = useContext(ThemeContext);
  const {name} = useContext(UserContext);

  return (
    <div className="border">
      <h3 className={themeColor}>UseContextPage</h3>
      <p>{name}</p>
    </div>
  );
}

总结:

三种使用方式,contextType, Consumer和useContext。

区别:

ContextType,使用简单,必须用在类组件上,只能通过该API订阅单一context.

Consumer,最广泛使用的

useContext,Hook方法,只能用在函数组件当中或者自定义的Hook当中。

react-redux用到Context,react-redux的<Provider />就是通过Context提供一个全局态的store,路由租金react-router通过Context管理路由状态等。

在React组件开发中,如果用好Context,可以让你的组件变得强大,而且灵活。

原文地址:https://www.cnblogs.com/starof/p/13383508.html