React-context 传值demo

890 阅读2分钟

React 传值问题 ---- Context

Context

01/什么是context?

Context 提供了一个无需为每层组件手动添加 props,就能在组件树间进行数据传递的方法。

02/为什么要用context?

在一个典型的 React 应用中,数据是通过 props 属性自上而下(由父及子)进行传递的,但这种做法对于某些类型的属性而言是极其繁琐的(例如:地区偏好,UI 主题),这些属性是应用程序中许多组件都需要的。Context 提供了一种在组件之间共享此类值的方式,而不必显式地通过组件树的逐层传递 props。

03/怎么使用?

context有两个属性provider和consumer , provider用来传递我们需要传递的数据 , consumer见名知义即消费者 , 用来接收我们传递过来的数据

流程如下:

  • createContext

    通过createContent创建一个MyContext对象

    const MyContext = React.createContext(defaultValue);
    
  • Context.Provider

    作为数据来源,为需要用到数据的组件提供数据

    <MyContext.Provider value={/* 某个值 */}>
    
  • Context.Consumer

    作为使用数据方

    <MyContext.Consumer>
      {value => /* 基于 context 值进行渲染*/}
    </MyContext.Consumer>
    
  • Class.contextType(暂时没搞懂)

04/个人理解

可以把context当做一个简化版的redux(store) , A把数据存在仓库里面,当A的儿子或者孙子想要仓库里的东西的时候,可以去仓库里面取出来用就好

05/demo

  • 我现在有一个组件ContextDemo需要把state里面的数据共享出去,Consumers组件需要使用和修改共享出去的数据

    <ContextDemo state={...this.state}>
       <Toolbar>
       		<Consumers/>
        </Toolbar>
    </ContextDemo>
    
  • ContextDemo组件

    import React, { Component } from 'react';
    import { Toolbar } from './Toolbar';
    
    export class ContextDemo extends React.Component {
    
      state = {
        toggle: true,
        handleToggle: () => this.handleToggle()
      }
    
      handleToggle = () => {
        this.setState({
          toggle: !this.state.toggle
        })
      }
    
      render() {
        return (
          <Toolbar />
        )
      }
    }
    
  • 实例化React.createContext

    import React, { Component } from 'react';
    import { Toolbar } from './Toolbar';
    
    //React.createContext({})里面有两个对象,Provider和Consumer,可以自定义一个contextName,在这里直接解构并export出去
    export const { Provider, Consumer} = React.createContext({})
    
    export class ContextDemo extends React.Component {
    
      state = {
        toggle: true,
        handleToggle: () => this.handleToggle()
      }
    
      handleToggle = () => {
        this.setState({
          toggle: !this.state.toggle
        })
      }
    
      render() {
        return (
         //Provider value存放需要共享出去的数据
          <Provider value={this.state}>
            <Toolbar />
          </Provider>
        )
      }
    }
    
  • Toolbar组件

    import React, { Component } from 'react';
    import { Consumers } from './Consumers';
    
    export function Toolbar(props) {
      return (
        <div>
          <Consumers />
        </div>
      );
    }
    
  • Consumers组件

    import React from 'react';
    
    //这里引入从ContextDemo中export的Consumer
    import { Consumer} from './index.js' 
    
    export class Consumers extends React.Component {
      render() {
        return <Consumer>
          {
          //注意这里是一个箭头函数,可以解构出来他们的参数
            ({ toggle, handleToggle}) =>
              <button onClick={() => handleToggle()}>
                {toggle ? '✔' : '❌'}
              </button>
          }
        </Consumer>
      }
    }
    
  • 效果

    • 浏览器查看结果

demo代码

06/ 注意事项

react官网写的很明白啦,context是一个实验性的api,在未来的版本中可能会被移除或者有较大的改动,还是尽量谨慎使用吧....