首页 > 其他分享 >react useContext

react useContext

时间:2023-01-30 17:45:56浏览次数:48  
标签:React const react useContext 组件 return red

一、什么是useContext

在 React class 式中父组件向子组件传递参数可以通过 props ,context。但是在函数式组件中需要向多层组件传递数据时,此时就可以使用 useContext/

二、useContext的作用

1.useContext可以帮助我们跨越组件层级直接传递变量,实现数据共享。

  • 这里要注意的是,很多同学觉得可以使用useContext结合useReducer来替代redux,其实两者的作用是不同的。
  • useContext:解决组件间传值的问题。
  • redux:统一管理应用状态。
  • 所以,我们可以使用useContext结合useReducer来模拟一个小型redux场景,而无法替代redux

2.Context的作用就是对它所包含的组件树提供全局共享数据的一种技术。

三、代码示例

import React, { useState } from "react";

let Theme = React.createContext("red");

const Inner = () => {
  let color = React.useContext(Theme);
  return <div><span style={{color: color}}>文字</span></div>
}

const Con = () => {
  return <Inner />
}

const Side = () => {
  console.log("side")
  return <><span>side</span></>
}


export default function App() {
  const [color, setColor] = useState("red")
  
  return (
    <div className="App">
      <button onClick={() => setColor("red")}>红色</button>
      <button onClick={() => setColor("green")}>绿色</button>
      <Theme.Provider value={color}>
        <Con />
        <Side />
      </Theme.Provider>
    </div>
  );
}

在上面的例子中,我通过在顶层创建 Provider 组件,深层次的子组件通过 useContext 取得 值,这样使得在父组件修改 context 的值之后,子组件也能取得相对应的值,并重新渲染。

需要注意的是,useContext 函数接收的参数对象是 context 自身。

存在于Provider 组件下的子组件在context 的值发生变化后,都会重新渲染,这样可能会引发一些性能问题,我们可以通过 memo 去避免一些不必要的重渲染。

const Side = memo(() => {
  console.log("side")
  return <><span>side</span></>
})

Context 是通过新旧值检测来确定变化,使用了与Object.is相同的算法。

如果传给Context 是个字面对象的话,有可能使得每次值的检测都会使得子组件重新渲染。

import React, { useState, memo } from "react";

let Theme = React.createContext({color:"red"});

const Inner = memo(() => {
  let theme = React.useContext(Theme);
  console.log("Inner")
  return <div><span style={{color: theme.color}}>文字</span></div>
})

const Con = () => {
  
  return <Inner />
}

const Side = memo(() => {
  console.log("side")
  return <><span>side</span></>
})


export default function App() {
  const [color, setColor] = useState("red")
  const [count, setCount] = useState(0);
  return (
    <div className="App">
      <div>
        {count}
        <button onClick={() => setCount((v) => v + 1 )}>count</button>
      </div>
      <button onClick={() => setColor("red")}>红色</button>
      <button onClick={() => setColor("green")}>绿色</button>
      <Theme.Provider value={{color}}>
        <Con />
        <Side />
      </Theme.Provider>
    </div>
  );
}

上述的代码中,因为父组件 App 重新渲染时提供给Conext 的都是一个新的字面量对象,导致Inner 组件会在父组件的每次重渲染中去跟着重新渲染,这实际上是没有必要的。

 
import React, { useState, memo } from "react";

let Theme = React.createContext({color:"red"});

const Inner = memo(() => {
  let theme = React.useContext(Theme);
  console.log("Inner")
  return <div><span style={{color: theme.color}}>文字</span></div>
})

const Con = () => {
 
  return <Inner />
}

const Side = memo(() => {
  return <><span>side</span></>
})


export default function App() {
  const [theme, setTheme] = useState({color: "red"})
  const [count, setCount] = useState(0);
  return (
    <div className="App">
      <div>
        {count}
        <button onClick={() => setCount((v) => v + 1 )}>count</button>
      </div>
      <button onClick={() => setTheme({color: "red"})}>红色</button>
      <button onClick={() => setTheme({color: "green"})}>绿色</button>
      <Theme.Provider value={theme}>
        <Con />
        <Side />
      </Theme.Provider>
    </div>
  );
}

通过上面的修改后,使得 Inner 避免了不必要的渲染。

标签:React,const,react,useContext,组件,return,red
From: https://www.cnblogs.com/momo798/p/17076798.html

相关文章

  • 玩转web3第一篇——web3-react
    概况web3-react是由NoahZinsmeister开发的一个web3框架,主要功能是实时获取DApp里的关键数据(如用户当前连接的地址、网络、余额等)。Noah也是著名的去中心化交易所uniswap......
  • react官方文档-高级部分-context学习
    前言:想捡回前端开发,还是得重学react语法,很多都忘了,而且好几年过去,语法也发生了很大的变化。另外,手册只是最基本的介绍,让你知道有这种用法,想深入掌握,还需要在具体点上查资......
  • react+ antd 表格筛选
    表格的筛选事件是在table的onchange中发生的,其选中值在onchange的参数2中,参数1是分页器//应先定义pagination,这一步是为了第一次请求数据时配置pagination相关const......
  • 一文详解如何在基于webpack5的react项目中使用svg
    本文主要讨论基于webpack5+TypeScript的React项目(cra、craco底层本质都是使用webpack,所以同理)在2023年的今天是如何在项目中使用svg资源的。首先,假定您已经完成基于webpac......
  • react组件实例属性props
    propsprops简单使用classPersonextendsReact.Component{render(){return(<ul>......
  • 如何在react中使用bind方法?
    JavaScript自身特性说明如果传递一个函数名给一个变量,之后通过函数名()的方式进行调用,在方法内部如果使用this则this的指向会丢失,为了避免这种情况的出现,我们可以使用bind......
  • React --- jsx语法规则
    jsx语法规则:1、定义虚拟dom时,不要写引号//创建虚拟DOM 1constVDOM=<h1><span>hello,react</span></h1> 2、标签中混入JS表达式时要用{}1//定义属性和标签内容2c......
  • 【Reactor模型】事件驱动模型 - Reactor模型简述
    模型演进抛出一个问题:线程怎样才能高效地处理多个连接的业务?当一个连接对应一个线程时,线程一般采用[read->业务处理->send]的处理流程,如果当前连接没有数据可读,那么线程......
  • 【个人笔记】2023年搭建基于webpack5与typescript的react项目
    写在前面由于我在另外的一些文章所讨论或分析的内容可能基于一个已经初始化好的项目,为了避免每一个文章都重复的描述如何搭建项目,我在本文会统一记录下来,今后相关的文章直......
  • react,webpack,antd的版本依赖关系
    调试react导航栏的时发现,reactwebpackantd这三个基础框架之间隐含这版本兼容性关系。也就是说,这几个框架的版本必须协调适应。如果不匹配对应的版本,就会出现各种各样......