前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用 react Context API 的正确姿势

使用 react Context API 的正确姿势

作者头像
JS菌
发布2019-04-10 15:28:55
1.5K0
发布2019-04-10 15:28:55
举报
文章被收录于专栏:JS菌

本文介绍一下 React 中常见的 Context API 的使用方式。在使用 Context API 之前,我们还需要知道为啥要使用。❓

为啥要用 Context API

考虑到组件有可能 层层嵌套 ,在传 props 的过程中,如果书写大量的 ...propspropName={this.props.propValue} 会导致代码灰常丑陋 ?:

20190312085239.png

一层一层下来就像这样:

代码语言:javascript
复制
1<App>
2    <Switcher toggleState={this.state.toggle}>
3        <Pannel toggleState={props.toggleState}>
4            <div onClick={handleClick}>{props.toggleState ? '✔' : '❌'}

所以引入 Context API 就可以直接通过上下文跨层级获取数据:

如何使用

  • 然后创建 provider ?
  • 首先要引入 React 内置的 React Context API ?
  • 最后创建 consumer ?

创建 Provider

增加一个名为 ToggleContext.js 的文件作为上下文?,里头定义一系列需要跨层级使用的 state 和 function

代码语言:javascript
复制
 1import React, { createContext } from 'react'
 2
 3// 1. 使用 createContext 创建上下文
 4const ToggleContext = createContext({
 5    toggle: true,
 6    handleToggle: () => {}
 7})
 8
 9// 2. 创建 Provider
10export class ToggleProvider extends React.Component {
11
12    // 注意书写顺序;handleToggle 作为箭头函数不能 bind 因此需要写在上面;如果不喜欢这样的顺序则可以书写普通函数放在下面但记得 bind
13    handleToggle = () => {
14        this.setState({ toggle: !this.state.toggle })
15    }
16
17    // 2-1. 重写 state 
18    state = {
19        toggle: true,
20        handleToggle: this.handleToggle
21    }
22
23    render() {
24        // 2-2. 通过 Provider 组件的 value 将 state 提供出去
25        return (
26            <ToggleContext.Provider value={this.state}>
27                {this.props.children}
28            </ToggleContext.Provider>
29        ) 
30    }
31}
32
33// 3. 创建 Consumer
34export const ToggleConsumer = ToggleContext.Consumer
35

上面的代码主要分为三大部分:

代码语言:javascript
复制
1// 创建 Context
2const ToggleContext = createContext()
3
4// 创建 Provider
5export class ToggleProvider extends React.Component {}
6
7// 创建 Consumer
8export cnost ToggleConsumer = ToggleContext.Consumer

我们理一下步骤?‍

  • 首先,我们需要引入 createContext 上下文并调用,传入我们希望在其他层级组件中使用的 state 和改变 state 的方法,注意这里的 state 和方法只是一个“骨架”,后面的 Provider 会覆盖
  • 接下来创建 Provider 这里头维护真正的 state,并通过 render 函数里面的 Context.Provider 组件的 value 属性提供这些方法
  • 然后创建 Consumer,直接导出 Context.Consumer 给外部使用即可

使用 Provider

ToggleProvider 组件包装了一系列共享的状态,为了使用这些组件的状态,我们直接将其添加到 App 组件中:

代码语言:javascript
复制
 1import React from 'react';
 2import { ToggleProvider } from './ToggleContext' // 1. 获取 Provider
 3
 4function App() {
 5  // 2-1. 使用 ToggleProvider 组件
 6  // 2-2. 如果有其他组件一样可以共享 state
 7  return (
 8    <ToggleProvider>
 9      <Switcher></Switcher>
10      {/* 其他组件仍然可以通过 props 访问到共享的 state */}
11    </ToggleProvider>
12  );
13}
14
15// ...
16export default App;

使用 Provider 比较简单直接作为父组件包裹在上层即可。如果组件内部有其他多个组件,这些组件都可以共享 Provider 提供的 state

使用 Consumer

  • 通过 Consumer 直接使用 props 传递的 state 属性在 render 函数中渲染即可
  • 如果需要调用方法,则可调用 props 传递的函数
代码语言:javascript
复制
 1import React from 'react';
 2import { ToggleProvider, ToggleConsumer } from './ToggleContext' // 1. 获取 Provider 和 Consumer
 3
 4function App() {
 5  return (
 6    <ToggleProvider>
 7      <Switcher></Switcher>
 8    </ToggleProvider>
 9  );
10}
11
12const Switcher = () => {
13  return <Pannel />
14}
15
16const Pannel = () => {
17  // 在多个层级内直接通过 props 获取 state 和方法,调用方法改变 state
18  return (
19    <ToggleConsumer>
20      {({ toggle, handleToggle }) => <div onClick={() => handleToggle()}>{ toggle ? '✔' : '❌'}</div>}
21    </ToggleConsumer>
22  )
23}
24
25export default App;
26

直接在子组件内部通过 props 调用即可

小结

另外附上一个简易版的 Context:

  • 通过 createContext 创建一个名为 color 的 context
  • 通过 Provider 的 value 属性传值
  • 通过 Consumer 的 props 接收值
代码语言:javascript
复制
 1import React, { createContext } from "react";
 2
 3const { Provider, Consumer } = createContext("color"); // 创建 Context 引用 Provider 和 Consumer
 4
 5class DeliverComponent extends React.Component {
 6  // 维护一个 state
 7  state = {
 8    color: 'orange',
 9    handleClick: () => {
10      this.setState({ color: 'red' })
11    }
12  }
13  render() {
14    return (
15      <Provider value={this.state}>
16        <MidComponent />
17      </Provider>
18    )
19  }
20}
21
22const MidComponent = () => <Receiver />; // 中间包含多层级的组件
23
24const Receiver = () => ( // 需要使用的后代元素使用 Consumer
25  <Consumer>
26    {({ color, handleClick }) => <div style={{ color }} onClick={() => { handleClick() }}> Hello, this is receiver.</div>}
27  </Consumer>
28);
29
30const App = () => <DeliverComponent />;
31
32export default App;

参考:

  • https://blog.usejournal.com/sharing-state-using-reacts-context-api-bc2db94da46d
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-03-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 JS菌 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 为啥要用 Context API
  • 如何使用
    • 创建 Provider
      • 使用 Provider
        • 使用 Consumer
          • 小结
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档