Context passing value and life cycle in react

Assumptions:

There is a complex component tree in the project:

Context value passing purpose


Data is passed top-down (from parent to child) via props, but this is extremely cumbersome for certain types of props (e.g. locale preferences, UI themes) that are important to the application Required by many components in .

Context passing value advantages


Context provides a way to share such values ​​between components without having to explicitly pass props through the layers of the component tree.

When to use Context


Context is designed to share data that is "global" to a tree of components, such as the currently authenticated user, theme, or preferred language.

ContextAPI


1.React.createContext API 
功能:
创建一个 Context 对象。
//代码
//创建context对象的
import React from 'react'
let context=React.createContext();
export default context;

2.Context.Provider API
功能:
Provider 是context对象提供的内置组件  限定在某个作用域中使用context传值。
限定作用域传值。

3.Context.Consumer
context对象的内置组件
<MyContext.Consumer>
  {value => /* 基于 context 值进行渲染*/}
</MyContext.Consumer>
作用:监听订阅的context变更, 
这个函数接收当前的 context 值,返回一个 React 节点。

Project case: theme color switching.


1.创建context.js文件
  创建context对象  用来做context传值。
//创建context对象的
import React from 'react'
export default React.createContext();
2。使用context找到限定范围使用内置组件Provider
 {/* 使用Provider 内置组件限定context范围 */}
 {/* value 必填  context传递的值 */}
        <ThemeContext.Provider>
          <div className="Admin">
            <div className="LeftMenu">
              <LeftMenu></LeftMenu>
            </div>
            <div className="RightContent">
              <div className="RightContent-top">
                <TopHeader></TopHeader>
              </div>
              <div className="RightContent-bottom">
                <Dashborder></Dashborder>
              </div>
            </div>
</ThemeContext.Provider>

The browser reports an error:

3.在使用context的组件中进行订阅
左侧菜单组件
import React, { Component } from "react";
console.log(Component);
//引入context对象
import ThemeContext from "../components/context";
class LeftMenu extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }
  render() {
    return (
      <>
        <div>左侧菜单</div>
      </>
    );
  }
}
//class类组件存在contextType  绑定context对象
LeftMenu.contextType = ThemeContext;

Use after binding the context in the component:

Means to subscribe to the internals of the context component using this.context to obtain.

render() {
    //获取context
    let theme = this.context;
    return (
      <>
        <div className={theme}>左侧菜单</div>
      </>
    );
  }

Fixed subject changed to dynamic subject

修改了context文件代码
//定义默认主体色

export const themes = {
  dark: {
    backgroundColor: "#000",
    color: "#fff",
  },
  light: {
    backgroundColor: "#fff",
    color: "#000",
  },
};

//创建context对象的
import React from "react";
export const ThemeContext = React.createContext();
app.js文件中获取主题,动态切换主题。使用主题变量
constructor(props) {
    super(props);
    this.state = {
      //将固定的主体设置为state状态
      themeType: "dark",//控制主体切换
      nowTheme: themes["dark"],//获取当前默认主体
    };
  }
  render() {
    //解构获取
    let { nowTheme } = this.state;
    return (
      <>
        {/* 使用Provider 内置组件限定context范围 */}
        {/* value 必填  context传递的值 */}
        <ThemeContext.Provider value={nowTheme}>

Use this.context in the subscription component to get the subscription

render() {
    //获取context
    let { backgroundColor, color } = this.context;
    return (
      <>
      //直接绑定行内css
        <div style={
    
    { backgroundColor: backgroundColor, color: color }}>
          左侧菜单
        </div>
      </>
    );
  }

The user clicks the buttons of other components to modify the theme to change the theme

注意:不能直接使用this.context修改变量值
//可以在provider组件上 value中携带修改函数传递。在订阅组件中获取修改方法,执行反向传递值。
//修改主题变量方法
  changeTheme(type) {
    console.log("测试", type);
    this.setState({ themeType: type, nowTheme: themes[type] });
  }
  render() {
    //解构获取
    let { nowTheme } = this.state;
    return (
      <>
        {/* 使用Provider 内置组件限定context范围 */}
        {/* value 必填  context传递的值 */}
        <ThemeContext.Provider
          value={
    
    { ...nowTheme, handler: this.changeTheme.bind(this) }}
        >
          <div className="Admin">
            <div className="LeftMenu">
              <LeftMenu></LeftMenu>
            </div>
            <div className="RightContent">
              <div className="RightContent-top">
                <TopHeader></TopHeader>
              </div>
              <div className="RightContent-bottom">
                <Dashborder></Dashborder>
              </div>
            </div>
          </div>
        </ThemeContext.Provider>
      </>
    );
 //在订阅组件中直接使用
 //修改主题的方法
  change(themeType) {
    console.log(themeType);
    //获取provider传递方法
    let { handler } = this.context;
    handler(themeType);
  }
  render() {
    let { themeButton } = this.state;
    return (
      <>
        <div>
          <span>主题色:</span>
          <div>
            {/* 控制左侧菜单和上header背景色 */}
            {themeButton.map((item, index) => {
              return (
                <button key={index} onClick={this.change.bind(this, item.type)}>
                  {item.name}
                </button>
              );
            })}
          </div>
        </div>
      </>
    );

Add custom colors


 {/* 颜色选择器 */}
          背景色:
          <input
            type="color"
            name="selectbgColor"
            value={selectbgColor}
            onChange={this.changeColor.bind(this)}
          />
          字体色:
          <input
            type="color"
            name="selectColor"
            value={selectColor}
            onChange={this.changeColor.bind(this)}
          />
          <button onClick={this.yesHandler.bind(this)}>确认</button>
   //代码区域操作事件向父级传递参数
     //确认修改
  yesHandler() {
    let { myhandler } = this.context;
    let { selectbgColor, selectColor } = this.state;
    console.log(selectbgColor, selectColor);
    myhandler(selectbgColor, selectColor);
  }

Add monitoring context changes


 {/*监听context value值*/}
          <ThemeContext.Consumer>
            {(value) => {
              let { backgroundColor, color } = value;
              return (
                <>
                  <span>背景色:{backgroundColor}</span>
                  <span>文字色:{color}</span>
                </>
              );
            }}
          </ThemeContext.Consumer>

class component life cycle


Component life cycle explanation: the whole process from component initialization to destruction.

Three types of life cycle:

  • Mounting: inserted into the real DOM

  • Updating: is being re-rendered

  • Unmounting: moved out of the real DOM

第一个阶段:
代码演示第一个阶段初始化挂载阶段
import React, { Component } from "react";

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {};
    console.log("初始化");
  }
  componentDidMount() {
    console.log("挂载完成");
  }
  render() {
    console.log("渲染");
    return (
      <>
        <div>测试</div>
      </>
    );
  }
}

export default App;

Added pre-mount cycle

 UNSAFE_componentWillMount() {
    console.log("挂载之前");
  }
 //18.x 版本中UNSAFE_ 前缀
第二个阶段:更新阶段
能触发类组件更新  props state

Added pre-update cycle

componentWillUpdate() {
    console.log("更新之前");
}
第三阶段卸载:
 //卸载周期
  componentWillUnmount() {
    console.log("组件卸载");
  }

Common cycle:

After the test is completed: Version 18 directly uses the above three cycles.

react推荐网络请求在componentDidMount
卸载清除副作用   componentWillUnmount

Confirm whether the current component update cycle

//确认是否更新周期
  //必须带返回值  true  false
  //提升性能
  shouldComponentUpdate(nextProps, nextState, nextContext) {
    console.log(nextProps);
    if (nextProps.name == this.props.name) return false;
    else return true;
  }
  不写该周期默认是执行更新
1.componentWillMount() - 在染之前执行,在客户端和服务器端都会执行.
2.componentDidMount() - 是挂在完成之后执行一次
3.componentWillReceiveProps() - 当从父类接收到 props 并且在调用另一个渲染器器之前调用。4.shouldComponentUpdatel) -根据特定条件返回 true 或 false如果你希望更新组件,请返回true 否则返它返回 false。
5.componentWillUpdate() - 是当前组件state和props发生变化之前执行
6.componentDidUpdate()-是当前组件state和props发生变化执行
7.componentWillUnmount0) - 从 DOM 卸载组件后调用。用于清理内存空间

Guess you like

Origin blog.csdn.net/m0_74331185/article/details/129621320