• React Hooks系列之useContext


    useContext介绍

    接收一个 context 对象(React.createContext 的返回值)并返回该 context 的当前值。当前的 context 值由上层组件中距离当前组件最近的 <MyContext.Provider> 的 value prop 决定。

    当组件上层最近的 <MyContext.Provider> 更新时,该 Hook 会触发重渲染,并使用最新传递给 MyContext provider 的 context value 值。即使祖先使用 React.memo 或 shouldComponentUpdate,也会在组件本身使用 useContext 时重新渲染。

    别忘记 useContext 的参数必须是 context 对象本身 useContext(MyContext)
    相当于 class 组件中的 static contextType = MyContext 或者 <MyContext.Consumer>。

    正确: useContext(MyContext)
    错误: useContext(MyContext.Consumer)
    错误: useContext(MyContext.Provider)
    

    调用了 useContext 的组件总会在 context 值变化时重新渲染。如果重渲染组件的开销较大,你可以 通过使用 memoization 来优化。

    注意:useContext(MyContext) 只是让你能够读取 context 的值以及订阅 context 的变化。你仍然需要在上层组件树中使用 <MyContext.Provider> 来为下层组件提供 context。


    useContext使用

    基本使用

    import React,{ useContext } from 'react'
    
    const people = React.createContext({name:'z',age:'18'})
    export default function UseContext() {
        const ctx=useContext(people)
        return (
            <div>
                <div>我是{ctx.name}---今年{ctx.age}岁</div>
            </div>
        )
    }
    

    再看一个例子

    import React,{ useContext } from 'react'
    // 创建一个 context
    const Context = React.createContext(0)
    
    // 组件一, Consumer 写法
    class Item1 extends PureComponent {
      render () {
        return (
          <Context.Consumer>
            {
              (count) => (<div>{count}</div>)
            }
          </Context.Consumer>
        )
      }
    }
    // 组件二, contextType 写法
    class Item2 extends PureComponent {
      static contextType = Context
      render () {
        const count = this.context
        return (
          <div>{count}</div>
        )
      }
    }
    // 组件三, useContext 写法
    function Item3 () {
      const count = useContext(Context);
      return (
        <div>{ count }</div>
      )
    }
    
    function App () {
      const [ count, setCount ] = useState(0)
      return (
        <div>
          点击次数: { count } 
          <button onClick={() => { setCount(count + 1)}}>点我</button>
          <Context.Provider value={count}>
            <Item1></Item1>
            <Item2></Item2>
            <Item3></Item3>
          </Context.Provider>
        </div>
        )
    }
    

    尝试变换区别

    import React, { createRef, createContext, useContext, PureComponent } from "react";
    import "./styles.css";
    
    const MyContext = createContext({})
    const Context = createContext(0)
    
    // 组件一, Consumer 写法
    class Child1 extends PureComponent {
      render() {
        return (
          <MyContext.Consumer>
            {
              ({name, age}) => (<div>{name}- {age}</div>)
            }
          </MyContext.Consumer>
        )
      }
    }
    
    // 组件二, useContext 写法
    const Child2 = () => {
      // const count = useContext(Context)
      const cxt = useContext(MyContext)
      return (
        <div>
          <p>{cxt.name}</p>
          <p>{cxt.age}</p>
          <p>{count}</p>
        </div>
      )
    }
    
    // 组件三, contextType 写法
    class Child3 extends PureComponent {
      static contextType = MyContext
      render() {
        const {name, age} = this.context
        return (
          <div>{name} --- {age}</div>
        )
      }
    }
    
    const App = () => {
      return (
        <>
          <MyContext.Provider value={{name:'用户名', age:20}}>
            child1:<Child1 />
            child2:<Child2 />
            child3:<Child3 />
          </MyContext.Provider>
        </>
      )
    };
    
    export default App;
    
    

    如果不清楚Context可查看 官网

    注意:
    context 中的 ProviderConsumer,在类组件函数组件中都能使用,Consumer多个context嵌套麻烦。
    contextType 只能在类组件中使用,因为它是类的静态属性,多个context无法处理
    useContext 写法简单,处理多个就写多个useContext

  • 相关阅读:
    CTFHub_2020数字中国创新大赛虎符网络安全赛道Webeasy_login(源码泄露、JWTNone攻击)
    CTFHub_2021津门杯Webhate_php(通配符绕过正则匹配)
    二叉树的序列化与反序列化
    软考高级及杭州E类人才申请经验分享
    推理框架概览
    Juniper初始化配置
    公务员、事业编、国企职工都有什么区别?不要再糊里糊涂的求职了
    upload labs120通关手册
    在docker中启动arthas
    超标量处理器设计 pdf
  • 原文地址:https://www.cnblogs.com/tommymarc/p/16150409.html
Copyright © 2020-2023  润新知