惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
D
Docker
Microsoft Security Blog
Microsoft Security Blog
Google DeepMind News
Google DeepMind News
M
MIT News - Artificial intelligence
P
Proofpoint News Feed
Engineering at Meta
Engineering at Meta
Y
Y Combinator Blog
Vercel News
Vercel News
F
Fortinet All Blogs
B
Blog
Recent Announcements
Recent Announcements
A
About on SuperTechFans
GbyAI
GbyAI
T
The Blog of Author Tim Ferriss
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - Franky
MongoDB | Blog
MongoDB | Blog
Stack Overflow Blog
Stack Overflow Blog
B
Blog RSS Feed
C
Check Point Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
V
Visual Studio Blog
月光博客
月光博客

博客园 - 沐子馨

一文讲透 Multi-Agent 四大协作模式:Workflow、Supervisor、Hierarchical 与 Swarm 花几天把 DeepSeek Harness 跑了个遍,跟你说说值不值得装 Loop 不够用了?AI 工程下一站叫 Graph Agent 审代码总塞满上下文,怎么解? 什么是Agent? Agent Loop:从对话式 AI 到自主智能体的范式跃迁 解锁图数据建模的奥秘 基于 Neo4j 与 Milvus 的图RAG系统搭建指南 解决复杂推理难题:KG-RAG 在大模型中的应用 RAG 评估常用工具简介 RAG系统效果不好?一文看懂如何进行系统评估 写出让 AI “秒懂”的技能Skill 深入理解 RAG 中的格式化生成与函数调用 解锁 RAG 系统中的高级检索与重排序策略 掌握查询重构与智能路由的艺术 告别黑盒:手把手实现一个可解释、可调试的 Text2SQL 代理系统 告别简单向量搜索:RAG 中的高级查询构建与优化策略 深入理解 RAG 中的混合搜索策略 告别基础检索:掌握 RAG 中的句子窗口与递归路由策略 构建多模态检索系统:Milvus 部署、Schema 设计与混合检索实践 向量数据库原理与实战:从核心机制到 FAISS 应用 多模态向量嵌入:从文本到图像的语义统一与 RAG 应用 构建高效 RAG 的基石:深度解析 Embedding 模型原理与优化 All-in-RAG:解锁大模型“开卷考试”的终极能力 AI Agent 是如何思考的?一文读懂推理与决策引擎 终端革命:AI Agent 正在重新定义命令行 给企业装上“AI 大脑”:AgentSpace 如何从“手动检索”跨越到“智能决策”? Agentic 框架快速概览 AI 智能体交互如何带领它走出对话框,从屏幕像素迈向真实物理世界 高级提示词技巧如何带领大模型走出“一本正经胡说八道”的误区?
react useContext
沐子馨 · 2023-01-30 · via 博客园 - 沐子馨

一、什么是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 避免了不必要的渲染。