react中context传值和生命周期详解

目录
  • context传值用途
  • Context传值优点
  • 何时使用 Context
  • ContextAPI
  • 项目案例:主题色切换。
  • 添加自定义颜色
  • 添加监听context变化
  • 类组件的生命周期

假设:

项目中存在复杂组件树:

context传值用途

数据是通过 props 属性自上而下(由父及子)进行传递的,但这种做法对于某些类型的属性而言是极其繁琐的(例如:地区偏好,UI 主题),这些属性是应用程序中许多组件都需要的。

Context传值优点

Context 提供了一种在组件之间共享此类值的方式,而不必显式地通过组件树的逐层传递 props。

何时使用 Context

Context 设计目的是为了共享那些对于一个组件树而言是“全局”的数据,例如当前认证的用户、主题或首选语言。

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 节点。

项目案例:主题色切换。

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>

浏览器报错:

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;

组件中绑定context之后使用:

意味着订阅context组件的内部使用this.context获取。

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

固定主体修改为动态主体

修改了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}>

订阅组件中使用this.context获取订阅

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

用户点击其他组件修改主题的按钮来变更主题

注意:不能直接使用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>
      </>
    );

添加自定义颜色

 {/* 颜色选择器 */}
          背景色:
          <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);
  }

添加监听context变化

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

类组件的生命周期

组件生命周期解释:组件初始化到销毁整个过程。

生命周期三类:

  • Mounting(挂载):已插入真实 DOM
  • Updating(更新):正在被重新渲染
  • Unmounting(卸载):已移出真实 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;

添加了挂载之前周期

 UNSAFE_componentWillMount() {
    console.log("挂载之前");
  }
 //18.x 版本中UNSAFE_ 前缀

第二个阶段:更新阶段
能触发类组件更新  props state

添加了更新之前周期

componentWillUpdate() {
    console.log("更新之前");
}

第三阶段卸载:

 //卸载周期
  componentWillUnmount() {
    console.log("组件卸载");
  }

常用周期:

测试完成之后:18版本直接使用周期以上三个。

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

确认当前组件是否更新周期

//确认是否更新周期
  //必须带返回值  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 卸载组件后调用。用于清理内存空间

到此这篇关于react中context传值和生命周期的文章就介绍到这了,更多相关react context传值和生命周期内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • React 中的 useContext使用方法

    目录 什么是上下文呢? useContext使用的方法: 1.要先创建createContex 2.Provider 指定使用的范围 3.最后使用useContext useContext就是上下文 什么是上下文呢? 全局变量就是全局的上下文,全局都可以访问到它:上下文就是你运行一段代码,所要知道的所有变量 useContext使用的方法: 1.要先创建createContex 使用createContext创建并初始化 const C = createContext(null); 2.Prov

  • React中的Context应用场景分析

    Context定义和目的 Context 提供了一种在组件之间共享数据的方式,而不必显式地通过组件树的逐层传递 props. 应用场景 哪些数据会需要共享? Context 设计目的是为了共享那些对于一个组件树而言是**"全局"的数据**,例如当前认证的用户.主题或首选语言. 使用步骤 1. 创建并初始化Context const MyContext = createContex(defaultValue); 创建一个 Context 对象.当 React 渲染一个订阅了这个 Cont

  • React源码分析之useCallback与useMemo及useContext详解

    目录 热身准备 初始化mount mountCallback 更新 update 使用场景 总结 热身准备 createContext Provider Consumer useContext 初始化mount&更新update 总结 热身准备 useCallback和useMemo是一样的东西,只是入参有所不同. useCallback缓存的是回调函数,如果依赖项没有更新,就会使用缓存的回调函数: useMemo缓存的是回调函数的return,如果依赖项没有更新,就会使用缓存的return:

  • 教你react中如何理解usestate、useEffect副作用、useRef标识和useContext

    目录 1.usestate 1.1一般使用 1.2 useState回调函数作为参数 2.useEffect副作用 2.1 useEffect副作用及其使用 2.2 useEffect清理副作用 2.3 useEffect发送网络请求 3.自定义hook函数 4.useRef的使用 5.useContext的使用 1.usestate 1.1一般使用 注意:useState 的初始值(参数)只会在组件第一次渲染时生效.也就是说,以后的每次渲染,useState 获取到都是最新的状态值,React

  • react中关于Context/Provider/Consumer传参的使用

    目录 Context/Provider/Consumer传参使用 Context 使用context向后代组件传参 Context/Provider/Consumer传参使用 react context这个api很少用到,所以一直不太清楚如何使用,最近在看antd的项目源码时,发现在组件中有类似Template.Comsumer的写法,一时没反应过来,本着碰到不懂得都要追根究底的原则,下面好好学习一下,Context这个api的使用 Context 作用 上下文(Context) 提供了一种通过

  • 基于React Context实现一个简单的状态管理的示例代码

    目录 前言 封装一个父组件用来包裹其他子组件 子组件如何获取数据呢 class Component 方式 context.Consumer useContext 总结 参考 前言 在大多数情况下,我们开发项目都需要一个状态管理,方便我们在全局共享状态库,在React生态里比较流行的几个库 redux.mobx.recoil 但是对于小项目,我们完全可以自己封装一个状态管理,减少一个包的安装就可以减小打包以后的项目体积. 主要分两步: 封装一个顶层组件提供数据 子组件获取数据和更新数据 封装一个父

  • React中的生命周期详解

    目录 react生命周期 常用的生命周期 不常用的生命周 完整的生命周期图 react生命周期 函数组件无生命周期,生命周期只有类组件才拥有 生命周期函数指在某一时刻组件会自动调用并执行的函数. React每个类组件都包含生命周期方法,以便于在运行过程中特定的阶段执行这些方法. 例如:我们希望在第一次将其呈现到DOM时设置一个计时器Clock.这在React中称为“安装”.我们也想在删除由产生 的DOM时清除该计时器Clock.这在React中称为“卸载”. 一般分为:挂载.更新.卸载 常用的生

  •  Spring 中 Bean 的生命周期详解

    目录 前言 1.Bean 生命周期 2.代码演示 总结 前言 Java 中的公共类称之为 Bean 或 Java Bean,而 Spring 中的 Bean 指的是将对象的生命周期,交个 Spring IoC 容器来管理的对象.所以 Spring 中的 Bean 对象在使用时,无需通过 new 来创建对象,只需要通过 DI(依赖注入),从 Spring 中取出要使用的对象即可. 那么 Spring 中,Bean 的生命周期又有哪些呢?接下来,我们一起来看. 1.Bean 生命周期 Spring

  • JavaWEB中Servlet的生命周期详解

    目录 一.什么是Servlet 生命周期? 二.Servlet 是由谁来维护的? 三.Servlet 对象 是什么时候创建的? 四.测试 Tomcat 什么时候被销毁? 总结 一.什么是Servlet 生命周期? Servlet 对象什么时候被创建? Servlet对象什么时候被销毁? Servlet 对象创建了几个? Servlet 对象的声明周期表示:Servlet 对象从出生到销毁的过程是怎样的 二.Servlet 是由谁来维护的? Servlet 是由 Tomcat 服务器全权负责的,程

  • Java中Servlet的生命周期详解

    目录 Web基础和HTTP协议 什么是Servlet Servlet的生命周期 Web基础和HTTP协议 ┌─────────┐ ┌─────────┐ │░░░░░░░░░│ │O ░░░░░░░│ ├─────────┤ ├─────────┤ │░░░░░░░░░│ │ │ ├─────────┤ │ │ │░░░░░░░░░│ └─────────┘ └─────────┘ │ request 1 │ │─────────────────────>│ │ request 2 │ │───

  • Spring配置使用之Bean生命周期详解

    基本概念 Spring 中的 Bean 的生命周期,指的是 Bean 从创建到销毁的过程. 下面来探究下几个有关 Bean 生命周期配置的属性. lazy-init lazy-init 表示延迟加载 Bean,默认在 Spring IoC 容器初始化时会实例化所有在配置文件定义的 Bean,若启用了 lazy-init 则在调用 Bean 时才会去创建 Bean. 定义 Bean: public class Animals { public Animals(){ System.out.print

  • 基于Listener监听器生命周期(详解)

    一.Listener生命周期 listener是web三大组件之一,是servlet监听器,用来监听请求,监听服务端的操作. listener分为:(都是接口类,必须实现相应方法) 1.生命周期监听器(3个) ServletContextListener requestDestroyed 在容器启动时被调用(在servlet被实例化前执行) requestInitialized 在容器销毁时调用(在servlet被销毁后执行) HttpSessionListener sessionCreated

  • 基于asp.net MVC 应用程序的生命周期(详解)

    首先我们知道http是一种无状态的请求,他的生命周期就是从客户端浏览器发出请求开始,到得到响应结束.那么MVC应用程序从发出请求到获得响应,都做了些什么呢? 本文我们会详细讨论MVC应用程序一个请求的生命周期,从一个控件到另一个控件是怎样被处理的.我们还会详细介绍一下整个请求的生命周期中,用到的相关组件.因为在平常的开发过程中,我们可能知道怎样去使用MVC框架来处理相关的请求,大部分的时候我们只是在controller和action方法之间做相关的处理,对于真正内在的运行机制可能不是很了解.其实

  • Java开发学习之Bean的作用域和生命周期详解

    目录 一.Bean 的作用域 二.Spring 的执行流程 三.Bean 的生命周期 一.Bean 的作用域 在之前学习Java基础的时候,有接触到作用域这样的概念.一个变量并不一定在任何区域都是有效的,限定这个变量的可用性的代码范围就是该变量的作用域. 但是在这里 Bean 的作用域的概念和以前所认为的作用域有所不同. Bean 的作用域是指 Bean 在 Spring 整个框架中的某种行为模式. 接下来,将会举一个案例来讲讲什么是作用域,什么是行为模式 案例概要: 创建一个共有的 Bean

  • servlet配置方法及其生命周期详解

    servlet配置: 在web.xml中,首先向服务器注册一个servlet.在<servlet>标签下 给定一个servlet名字,这个servlet-name是我们自己用的,方便我们用它对servlet进行配置. 1 <servlet-name>AServlet</servlet-name>然后指定一个全类名,这个是给服务器使用,服务器用来创建全类名对象的实例 1 <servlet-class>com.servlet.AServlet</servl

  • Android入门教程之组件Activity的生命周期详解

    目录 返回栈 Activity 状态 1. 运行状态 2. 暂停状态 3. 停止状态 4. 销毁状态 Activity 的生存期 onCreate() onStart() onResume() onPause() onStop() onDestroy() onRestart() 完整生存期 可见生存期 前台生存期 Activity 回收处理 返回栈 Android 中的 Activity 是可以层叠的,我们每启动一个新的 Activity,就会覆盖在原有的 Activity 之上,然后点击 Ba

随机推荐

其他