React Context 简易使用

7 篇文章 0 订阅

1 使用背景

为了跨组件进行数据传递,尤其是跨多级组件传递,使用context能简化流程,且更为清晰。需要注意的是,依赖context的组件,在context发生改变的时候会更新(不受shouldComponentUpdate控制)
需要注意的是:context比较为浅比较,如果父组件传递给子组件的context是一个新对象,则会触发子组件更新。

2 类组件的使用

注意:context一定要单独存放,否则可能会有引用问题,导致无法找到context,即import加载顺序

一、声明context

// context.js
import React from 'react';
export const NameContext = React.createContext("xxx");

二、在父组件上设置Provider

// App.js
import React from "react";
import Page01 from "./routes/page01";
import { NameContext } from "./context/Context";
// export const NameContext = React.createContext("xxx"); 不要在这里创建context,需要放在单独的文件里
function App() {
  return (
    <NameContext.Provider value="xiaopi3">
      <div>
        <h1>这是一个APP!</h1>
        <Page01 />
      </div>
    </NameContext.Provider>
  );
}

export default App;

三、在后辈组件中,声明contextType,即可使用this.context

// Page01.js
import React, { Component } from 'react'
import {NameContext} from '../../context/Context';

export default class Page01 extends Component {
  static contextType =  NameContext;
  render() {
    return (
      <div>
          <h1>当前是一个测试页面Page01!</h1>
          <div>{this.context}</div>
      </div>
    )
  }
}

四、改变context
一般而言如果需要传入改变context的方法,需要将其值和方法作为一个对象传递给provider的value (注意:value为浅比较,如果引用未改变则不会更新页面,所以此处使用类的state,因为调用setState后会生成一个新的state)

// App.js
import React from "react";
import Page01 from "./routes/page01";
import { NameContext } from "./context/Context";

class App extends React.Component {
  state = {
    name: "xxx",
    changeName: (name) => this.setState({ name }),
  };
  render() {
    return (
      <NameContext.Provider value={this.state}>
        <div>
          <h1>这是一个APP!</h1>
          <Page01 />
        </div>
      </NameContext.Provider>
    );
  }
}

export default App;

使用的时候:this.context.changeName(‘pp’)即可。

3 函数组件的使用

和类组件不同,函数组件无需声明contextType,但需要在render中使用consumer:

// 类组件
static contextType =  NameContext;
...
<div>{this.context}</div>
// 函数组件
import React from "react";
import { NameContext } from "../../../context/Context";

export default function Cp01() {
  return (
    <>
      我是N代子组件
      <NameContext.Consumer>
        {(context) => (
          <>
            <div>{context.name}</div>
            <button onClick={()=>context.changeName("pp")}>changeName</button>
          </>
        )}
      </NameContext.Consumer>
    </>
  );
}

注意:Context.Consumer内部需要一个函数作为子元素!接收当前context值,并返回react节点。

4 消费多个context

如果组件需要消费多个context,需要使用consumer来进行嵌套,同时传递value时也需要嵌套!

// provider嵌套
<ThemeContext.Provider value={theme}>
  <UserContext.Provider value={signedInUser}>
    <Layout />
  </UserContext.Provider>
</ThemeContext.Provider>

// consumer嵌套
<ThemeContext.Consumer>
  {theme => (
    <UserContext.Consumer>
      {user => (
        <ProfilePage user={user} theme={theme} />
      )}
    </UserContext.Consumer>
  )}
</ThemeContext.Consumer>

5 useContext

注意事项同非hook方式一样,在context更新时,该hook会触发组件重新渲染,即使父组件使用了React.memo或shouldComponentUpdate。

该hook接收context:useContext(MyContext) 相当于 class 组件中的 static contextType = MyContext 或者 <MyContext.Consumer>
注意:useContext(MyContext) 只是让你能够读取 context 的值以及订阅 context 的变化。你仍然需要在上层组件树中使用 <MyContext.Provider>来为下层组件提供 context。

使用hook改写部分代码:

// hook方式
import React,{useContext} from "react";
import { NameContext } from "../../../context/Context";

export default function Cp01() {
  const context = useContext(NameContext);
  return (
    <>
      Cp01
      <div>{context.name}</div>
      <button onClick={() => context.changeName("pp")}>changeName</button>
    </>
  );
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值