• React的Context的使用方法简介


    context

    定义: Context提供了一种方式,能够让数据在组件树中传递,而不必一级一级手动传递。

    API : createContext(defaultValue?)。

    使用方法:

    首先要引入createContext

    import React, { Component, createContext } from 'react';

     然后创建一个Context 

    const BatteryContext = createContext();

    然后用BatteryContext.Provider包裹组件并且传递属性值。

    <BatteryContext.Provider value={60}>
         <Middle />  //子组件
    </BatteryContext.Provider>

     为了方便看出效果,将定义一个子组件和一个孙组件。然后不通过子组件,孙组件直接取值

    import React, { Component, createContext } from 'react';
    
    const BatteryContext = createContext();
    
    //声明一个孙组件
    class Leaf extends Component {
      render() {
        return (
        
        )
      }
    }
    
    //声明一个子组件
    class Middle extends Component {
      render() {
        return <Leaf /> 
      }
    }
    
    class App extends Component {
      render(){
        return (
          <BatteryContext.Provider value={60}>
            <Middle />
          </BatteryContext.Provider>
        );
      }
    }
    
    export default App;

    孙组件需要BatteryContext.Consumer来接收值,Consumer里面不能直接渲染其他组件,而是要声明一个函数。函数的参数就是context的值。

    class Leaf extends Component {
      render() {
        return (
          <BatteryContext.Consumer>
            {
              battery => <h1>Battery : {battery}</h1>
            }
          </BatteryContext.Consumer>
        )
      }
    }

     效果图;

    这样没通过Middle组件来传递值,但是Leaf组件能通过context来获得属性。这就是context的基本用法。

    context不但能跨层级来传递属性值,还能在属性值发生变化的时候重渲染Consumer下面的元素,举个例子:
     
    在state中定义battery并赋值
    state = {
        battery: 60
      }
    然后做一个按钮,每次点击的时候都要battery减一。  代码:
    render() {
        const { battery } = this.state;
        return (
          <BatteryContext.Provider value={battery}>
            <button
              type="button"
              onClick={() => this.setState({ battery: battery - 1 })}
            >
              减减
            </button>
            <Middle />
          </BatteryContext.Provider>
        );
      }
    全部代码:
    import React, { Component, createContext } from 'react';
    
    const BatteryContext = createContext();
    
    //声明一个孙组件
    class Leaf extends Component {
      render() {
        return (
          <BatteryContext.Consumer>
            {
              battery => <h1>Battery : {battery}</h1>
            }
          </BatteryContext.Consumer>
        )
      }
    }
    
    //声明一个子组件
    class Middle extends Component {
      render() {
        return <Leaf />
      }
    }
    
    class App extends Component {
      state = {
        battery: 60
      }
      render() {
        const { battery } = this.state;
        return (
          <BatteryContext.Provider value={battery}>
            <button
              type="button"
              onClick={() => this.setState({ battery: battery - 1 })}
            >
              减减
            </button>
            <Middle />
          </BatteryContext.Provider>
        );
      }
    
    }
    
    export default App;

     效果图: 

    这样每次点击都会使battery得数值发生变化,从而重渲染Consumer下面的元素。

    如果有多个Context该怎么做呢?我们在创建一个 Context
    const OnLineContext = createContext();
    如果有多个context变量的话,只需要把Privider嵌套进来即可,顺序不重要。接下来声明online的Provider了。
    class App extends Component {
      state = {
        battery: 60,
        online: false
      }
      render() {
        const { battery, online } = this.state;
        return (
          <BatteryContext.Provider value={battery}>
            <OnLineContext.Provider value={online} >
              <button
                type="button"
                onClick={() => this.setState({ battery: battery - 1 })}
              >
                减减
            </button>
              <button
                type="button"
                onClick={() => this.setState({ online: !online })}
              >
                Switch
            </button>
              <Middle />
            </OnLineContext.Provider>
          </BatteryContext.Provider>
        );
      }
    与Provider类似。Consumer也需要嵌套,顺序不重要。只要Consumer需要声明函数,所以要注意语法。
    class Leaf extends Component {
      render() {
        return (
          <BatteryContext.Consumer>
            {
              battery => (
                <OnLineContext.Consumer>
                  {
                    online => <h1>Battery : {battery} , Online : {online.toString()}</h1>
                  }
                </OnLineContext.Consumer>
              )
            }
          </BatteryContext.Consumer>
        )
      }
    }

     

     全部代码:

    import React, { Component, createContext } from 'react';
    
    const BatteryContext = createContext();
    const OnLineContext = createContext();
    
    //声明一个孙组件
    class Leaf extends Component {
      render() {
        return (
          //与Provider类似。Consumer也需要嵌套,顺序不重要。只要Consumer需要声明函数,所以要注意语法。
          <BatteryContext.Consumer>
            {
              battery => (
                <OnLineContext.Consumer>
                  {
                    online => <h1>Battery : {battery} , Online : {online.toString()}</h1>
                  }
                </OnLineContext.Consumer>
              )
            }
          </BatteryContext.Consumer>
        )
      }
    }
    
    //声明一个子组件
    class Middle extends Component {
      render() {
        return <Leaf />
      }
    }
    
    class App extends Component {
      state = {
        battery: 60,
        online: false
      }
      render() {
        const { battery, online } = this.state;
        //接下来声明online的Provider了。如果有多个context变量的话,只需要把Privider嵌套进来即可,顺序不重要。
        return (
          <BatteryContext.Provider value={battery}>
            <OnLineContext.Provider value={online} >
              <button
                type="button"
                onClick={() => this.setState({ battery: battery - 1 })}
              >
                减减
            </button>
              <button
                type="button"
                onClick={() => this.setState({ online: !online })}
              >
                Switch
            </button>
              <Middle />
            </OnLineContext.Provider>
          </BatteryContext.Provider>
        );
      }
    
    }
    
    export default App;

    效果图:

    还有一个问题 , 如果Consumer向上找不到对应的Provider怎么办?
     
    其实即使找不到也不会报错,而是显示为空。那怎么设置默认值呢?
     
    那上面的demo举例 ,刚才我们设置的battery为60。如果Consumer向上找不到BatteryContext.Provider的值,我们可以这样设置默认值:
    const BatteryContext = createContext(30);
    这样BatteryContext.Consumer向上找不到值,就会取默认值30。
    context不仅仅只是可以传数值,也可以传函数。大家可以试试看。
    最后再提示一下大家,不要滥用context,不然会影响组件的独立性。 如果一个组件中只使用一个Context的话,就可以使用contextType代替Consumer。详见https://www.cnblogs.com/littleSpill/p/11221817.html
     
     
     
  • 相关阅读:
    Intellij idea使用过程中遇到的一些问题
    微信小程序云函数Windows下安装wx-server-sdk
    计算文件MD5的方法
    IntelliJ IDEA取消自动import所有import *
    在IntelliJ IDEA中使用VIM
    STS启动时卡在loading加载 dashboard.ui
    NoSuchMethodError
    BeanUtils.copyProperties和PropertyUtils.copyProperties的使用区别
    一致性哈希算法介绍
    Maven修改本地仓库路径
  • 原文地址:https://www.cnblogs.com/littleSpill/p/11221538.html
Copyright © 2020-2023  润新知