【前端知识】React 基础巩固(二十一)——Context 和 Spread Attributes

本文介绍了React中如何使用SpreadAttributes来传递对象属性,并详细讲解了Context的应用,包括非父子组件间的数据共享,以及Context的创建、Provider和Consumer的使用,展示了如何通过Context减少不必要的props传递,提高代码效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

React 基础巩固(二十一)——Context 和 Spread Attributes

1.使用Spread Attributes

import React, { Component } from "react";
import Home from "./Home";

export class App extends Component {
  constructor() {
    super();

    this.state = {
      info: { name: "outman", age: 30 },
    };
  }
  render() {
    const { info } = this.state;
    return (
      <div>
        <h2>App</h2>
        {/* 利用展开运算符传递对象 */}
        <Home {...info} />
      </div>
    );
  }
}

export default App;
import React, { Component } from "react";

export class Home extends Component {
  render() {
    const { name, age } = this.props;

    return (
      <div>
        <h2>name: {name}</h2>
        <h2>age: {age}</h2>
      </div>
    );
  }
}

export default Home;

2.Context的应用

非父子组件数据的共享

  • 一些数据需要在多个组件中共享时,在顶层一层层传递下去,对不需要改数据的中间层而言是一种冗余,需要使用 Context。
  • Context 提供了一种在组件之间共享此类值的方式,而不必显式地通过组件树的逐层传递 props
  • Context 设计目的是为了共享那些对于一个组件树而言是“全局”的数据,例如当前认证的用户、主题或首选语言

Context 的用法

  • theme-context.js (封装 context)
import React from "react";
// 创建一个Context
const ThemeContext = React.createContext();

export default ThemeContext;
  • Main.jsx(主文件)
import React, { Component } from "react";
import Home from "./Home";

import ThemeContext from "./theme-context";

export class App extends Component {
  constructor() {
    super();

    this.state = {
      info: { name: "outman", age: 30 },
    };
  }
  render() {
    const { info } = this.state;
    return (
      <div>
        <h2>App</h2>
        {/* 通过context中的Provider属性为后代提供数据 */}
        <ThemeContext.Provider value={{ color: "red", size: "30" }}>
          <Home {...info} />
        </ThemeContext.Provider>
      </div>
    );
  }
}

export default App;
  • Home.jsx(中间层)
import React, { Component } from "react";
import HomeInfo from "./HomeInfo";

export class Home extends Component {
  render() {
    return (
      <div>
        <HomeInfo />
      </div>
    );
  }
}

export default Home;
  • HomeInfo.jsx(需要使用 Context 内容的子孙组件)
import React, { Component } from "react";
import ThemeContext from "./theme-context";

export class HomeInfo extends Component {
  render() {
    // 获取数据并使用
    console.log(this.context);
    return <div>color: {this.context.color}</div>;
  }
}

// 设置组件的contextType为某个context
HomeInfo.contextType = ThemeContext;

export default HomeInfo;

Context 的其他用法

嵌套使用 Context

  • 在上例基础上,新增 user-context.js
import React from "react";
// 创建一个Context
const UserContext = React.createContext();

export default UserContext;
  • Main.jsx (嵌套使用多个 context)
import React, { Component } from "react";
import Home from "./Home";

import ThemeContext from "./theme-context";
import UserContext from "./user-context";

export class App extends Component {
  constructor() {
    super();

    this.state = {
      info: { name: "outman", age: 30 },
    };
  }
  render() {
    const { info } = this.state;
    return (
      <div>
        <h2>App</h2>
        {/* 嵌套使用 */}
        <UserContext.Provider value={{ nickname: "outman", age: "30" }}>
          {/* 通过context中的Provider属性为后代提供数据 */}
          <ThemeContext.Provider value={{ color: "red", size: "30" }}>
            <Home {...info} />
          </ThemeContext.Provider>
        </UserContext.Provider>
      </div>
    );
  }
}

export default App;
  • Home.jsx
    与上例一致

  • HomeInfo.jsx(嵌套使用)

import React, { Component } from "react";
import ThemeContext from "./theme-context";
import UserContext from "./user-context";

export class HomeInfo extends Component {
  render() {
    // 获取数据并使用
    console.log(this.context);
    return (
      <div>
        <h2>color: {this.context.color}</h2>
        {/* 嵌套使用 */}
        <UserContext.Consumer>
          {(value) => {
            return <h2>Info User: {value.nickname}</h2>;
          }}
        </UserContext.Consumer>
      </div>
    );
  }
}

// 设置组件的contextType为某个context
HomeInfo.contextType = ThemeContext;

export default HomeInfo;

Context 相关 API

  • React.createContext
    • 创建一个需要共享的 Context 对象
    • 如果一个组件订阅了 Context,那么这个组件会从离自身最近的那个匹配的 Provider 中读取到当前的 context 值
    • defaultValue 是组件在顶层查找过程中没有找到对应的 Provider,则使用的默认值
  • Context.Provider
    • 每个 Context 对象都会返回一个 Provider React 组件,它允许消费组件订阅 context 的变化
    • Provider 接收一个 value 属性,传递给消费组件
    • 一个 Provider 可以和多个消费组件有对应关系
    • 多个 Provider 可以嵌套使用,里层会覆盖外层数据
    • 当 Provider 的 value 值发生变化时,它内部的所有消费组件都会重新渲染
  • Class.contextType
    • 挂载在 class 上的 contextType 属性会被重赋值为一个由 React.createContext()创建的 Context 对象
    • contextType 能使 this.context 来小费最近 Context 上的值
    • 可以在任何生命周期中访问到它,包括 render 函数中
  • Context.Comsumer
    • Comsumer能使函数式组件订阅context
    • 需要函数作为子元素(function as child)做法
    • 函数接收当前的context值,返回一个React节点
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端Outman

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值