当前位置: 首页 > news >正文

React笔记_组件之间进行数据传递

目录

      • 父子组件传值- props
        • 父传子
        • 子传父
      • 嵌套组件传值-Context API
        • 概念
        • React.createContext API
        • Provider组件
          • 正确示例
          • 错误示例
        • 消费 Context
          • React.Consumer组件
          • useContext Hook
          • 区别
        • 使用场景
          • 举例说明-用户信息
      • 状态管理-Redux

父子组件传值- props

在React中父子组件传值是单向数据流 => 数据必须是由父级传到子级或者子级传递给父级层层传递!

父传子

父组件通过在子组件的JSX标签上添加属性的方式来传递数据,子组件通过 props 对象接收。

传递的数据类型是不受限制的 = > 可以是字符串、数字、数组、对象、函数、甚至JSX元素。

  • 父组件

      <son  子组件接收的属姓名=父组件的属性值></son>
    
    import  {useState} from 'react'
    import Funcom from '../component/Funcom'
    import Clcom from '../component/Clcom'export default function Page1(){const [num, setNum] = useState(1)return (<div>{/* 函数子组件 */}<Funcom num={num}/>{/* 类子组件 */}<Clcom num ={num}/><button onClick={()=>{setNum(preNum=>preNum+1)}}>editNum</button></div>)
    }
    
  • 子组件:

    • 函数子组件组件:在调用函数时将props作为参数传入;
      function FunSon(props){
      // props直接使用
      }
      
      export default function Fun(props){console.log('渲染了') // 无论有没有接收参数只要父组件更新都会重新渲染子组件return (<div><h4>函数子组件=={props.num}</h4></div>)
      }
      
    • 类子组件:通过this获取props
      class ClaSon extends React.Component{// this.props使用
      }
      
      import React from 'react'export default  class Clcom extends React.Component {render() {console.log('render')  // 无论有没有接收参数只要父组件更新都会重新渲染子组件return (<><h4>类组件=={this.props.num}</h4></>)}
      }
      
子传父

子组件不能直接修改父组件的状态(数据单向流动),果需要,父组件必须传递一个函数给子组件作为 prop,子组件在需要时调用这个函数,将数据作为参数传回给父组件。

  • 父组件
    <Son 子组件调用的方法名={父组件的方法}></Son>
    
  • 子组件
    // 当子组件想要修改父组件的数据时
    // val是要修改的值props.方法名(val) // 函数组件this. props.方法名(val) // 类组件
    
  • 举例说明
    父组件
    import  {useState} from 'react'
    import Funcom from '../component/Funcom'
    import Clcom from '../component/Clcom'export default function Page1(){const [num, setNum] = useState(1)function editNum(val){setNum(val)}return (<div>{/* 函数子组件 */}<Funcom num={num} editNum={editNum}/>{/* 类子组件 */}<Clcom num ={num}  editNum={editNum}/></div>)
    }
    函数子组件
    export default function Fun(props){return (<div><h4>函数子组件=={props.num}</h4><button onClick={()=>{props.editNum(props.num+2)}}>函数组件editNum</button></div>)
    }
    
    类子组件
    import React from 'react'export default  class Clcom extends React.Component {render() {console.log('render')return (<><h4>类组件=={this.props.num}</h4><button onClick={()=>{this.props.editNum(this.props.num+1)}}>类组件editNum</button></>)}
    }
    

嵌套组件传值-Context API

概念

Context API 是 React 提供的一种组件间通信机制,允许数据在组件树中直接传递,无需通过 props 逐层传递。

React.createContext API

React.createContext 是一个函数,用于创建一个Context对象 => 该对象是管理 “全局”或“跨组件”数据的容器和通信机制。

React.createContext(defaultValue)
  • 参数:defaultValue;

    当一个组件在树中找不到匹配的 Provider 时,React.Consumer/useContext就会返回这个 defaultValue;

    这个默认值对于测试组件或在没有提供 Provider 的情况下非常有用

  • 返回值:一个Context对象

    {$$typeof: Symbol(react.context), // React 内部用于识别类型的符号_currentValue: 'light',          // 内部保存的当前值Provider: { ... },               // Provider 组件Consumer: { ... },               // Consumer 组件 (已较少使用)displayName: undefined,          // 用于 React DevTools 显示的名称
    }
    
Provider组件

Provider组件是React.createContext函数返回对象的属性,允许消费组件订阅 Context 的变化。

<MyContext.Provider value={...}><!-- 子组件树-->
</MyContext.Provider>

value就是要传递给所有下层组件的数据,只要 value发生变化,所有订阅该 Context 的后代组件都会强制重新渲染,即使它们使用了 React.memo 或 shouldComponentUpdate。

正确示例
  const ThemContext = createContext({theme:'right', color: 'red'})const [theme, setTheme] = useState({theme:'right', color: 'red'})return (<div><ThemContext.Provider value={theme}>{/* 其中所有的子组件以及其子组件都可以获取到value */}<Funcom /><Clcom /></ThemContext.Provider></div>)
错误示例
<div><ThemContext.Provider value={{theme:'right', color: 'red'}}>{/* 其中所有的子组件以及其子组件都可以获取到value */}<Funcom /><Clcom /></ThemContext.Provider>    
</div>

每次渲染时,value={ theme:‘right’, color: ‘red’ }都会创建一个全新的对象,导致所有消费者不必要的重渲染。

消费 Context

kan su me

React.Consumer组件

React.Consumer是类组件中订阅 Context 变更的方式,函数组件已经逐渐使用useContext这个hook来替代了。

子元素是一个函数,函数的参数就是 ThemeContext 的当前值,返回值就是需要渲染的vodm;

 <ThemeContext.Consumer>{value=>{vdom}}</ThemeContext.Consumer>

举例说明

  • 将context提取为一个单独的文件themeContext

    import  {createContext} from 'react'
    export default createContext({theme:'right', color: 'red'})
    
  • 在顶级组件引入

    import  {useState} from 'react'
    import Funcom from '../component/Funcom'
    import Clcom from '../component/Clcom'
    import ThemContext from '../utils/themeContext'
    export default function Page1(){const [theme, setTheme] = useState({theme:'right', color: 'red'})function editTheme(){setTheme(prevalue => ({...prevalue, theme: prevalue.theme=='right' ? 'dack' : 'right',}))}return (<div><ThemContext.Provider value={theme}>{/* 其中所有的子组件以及其子组件都可以获取到value */}<Funcom /><Clcom /><button onClick={editTheme}>edittheme</button></ThemContext.Provider></div>)
    }
    
  • 子组件中若是不需要使用则完全不需要改变

  • 在想要使用的组件去消费,比如此处在孙组件使用

     import React from 'react'import  ThemeContext  from '../utils/themeContext'class SonFun2 extends React.Component{render(){console.log('孙组件')return(<ThemeContext.Consumer>{value=>(<><h4>今天的主题是:{value.theme}</h4><div>今天的颜色是:{value.color}</div></>)}</ThemeContext.Consumer>)}}
    

    当在顶级组件点击按钮修改value值时会重新渲染所有组件,包括子组件(因为通过setState去修改数据本身就会渲染所有子组件)

useContext Hook

useContext是函数组件中订阅 Context 变更的方式

const value = useContext(ThemeContext)

value就是要传递给所有下层组件的数据,只要 value发生变化,所有订阅该 Context 的后代组件都会强制重新渲染

举例说明

function SonFun(){const value = useContext(ThemeContext)return (<div><h4>function</h4><h4>今天的主题是:{value.theme}</h4><div>今天的颜色是:{value.color}</div></div>)
}
区别
函数组件类组件
方式useContext APIContext.consumer组件
语法只需要在函数顶部调用hook ,简单明了需要在组件jsx语法中嵌套一个函数,语法稍显冗长
易读性可以并行调用多个context,简单易懂若是存在多个context,容易造成回调地狱
性能基本相同基本相同
使用场景

推荐在值不经常改变的地方使用context,如主题切换用户信息认证管理一些全局的、许多组件都需要的数据

对于频繁更新的数据, 如表单输入、实时坐标等,Context 可能不是最优解,因为只要 Context 的 value 变化,所有消费该 Context 的组件都会重新渲染,即使它们只使用了 value 的一部分。

举例说明-用户信息

状态管理-Redux

redux


文章转载自:

http://re7HkI7L.rdLfk.cn
http://QiPzmjDf.rdLfk.cn
http://y9NB8SXm.rdLfk.cn
http://2g1bRhsI.rdLfk.cn
http://SE5Xgnu7.rdLfk.cn
http://mbNxbZZR.rdLfk.cn
http://LmFHM2KO.rdLfk.cn
http://I5EhoCY2.rdLfk.cn
http://ATZeiLyt.rdLfk.cn
http://CwXZlEpI.rdLfk.cn
http://SuojtiN7.rdLfk.cn
http://P7YRzM35.rdLfk.cn
http://ycOYGyZe.rdLfk.cn
http://dhTyU3tG.rdLfk.cn
http://Ws1jmUyb.rdLfk.cn
http://J32L6JM4.rdLfk.cn
http://Lb3FIhuI.rdLfk.cn
http://lSSY9C4N.rdLfk.cn
http://rANctCfm.rdLfk.cn
http://5UxkoysI.rdLfk.cn
http://SpuKHudi.rdLfk.cn
http://Mcidm952.rdLfk.cn
http://YJwNBjRL.rdLfk.cn
http://Wy9Pr2qT.rdLfk.cn
http://vV1aCGsn.rdLfk.cn
http://gProUpMf.rdLfk.cn
http://JUMNlHnP.rdLfk.cn
http://hCgjsaIG.rdLfk.cn
http://BMP1vGOY.rdLfk.cn
http://Wrnpsxss.rdLfk.cn
http://www.dtcms.com/a/366966.html

相关文章:

  • 《Java餐厅的待客之道:BIO, NIO, AIO三种服务模式的进化》
  • 【OpenHarmony文件管理子系统】文件访问接口解析
  • sealos部署k8s
  • (C题|NIPT 的时点选择与胎儿的异常判定)2025年高教杯全国大学生数学建模国赛解题思路|完整代码论文集合
  • 25高教社杯数模国赛【C题国一学长思路+问题分析】第二弹
  • 数学建模25c
  • 互联网大厂Java面试场景与问题解答
  • LeetCode 刷题【64. 最小路径和】
  • Rust+slint实现一个登录demo
  • Rust 文件操作终极实战指南:从基础读写到进阶锁控,一文搞定所有 IO 场景
  • 代码随想录算法训练营第二十八天 | 买卖股票的最佳实际、跳跃游戏、K次取反后最大化的数组和
  • 2025全国大学生数学建模C题保姆级思路模型(持续更新):NIPT 的时点选择与胎儿的异常判定
  • 2025反爬虫之战札记:从robots.txt到多层防御的攻防进化史
  • 23种设计模式——工厂方法模式(Factory Method Pattern)详解
  • C++ 学习与 CLion 使用:(七)if 逻辑判断和 switch 语句
  • docker中的mysql变更宿主机映射端口
  • Redis(43)Redis哨兵(Sentinel)是什么?
  • 【连载 7/9】大模型应用:大模型应用:(七)大模型使用工具(29页)【附全文阅读】
  • 从 GPT 到 LLaMA:解密 LLM 的核心架构——Decoder-Only 模型
  • 原型链和原型
  • 嵌入式学习 51单片机(3)
  • 详细学习计划
  • 深度解读《实施“人工智能+”行动的意见》:一场由场景、数据与价值链共同定义的产业升级
  • CLIP模型
  • 深度学习篇---SENet网络结构
  • JS初入门
  • 大数据开发计划表(实际版)
  • TypeScript 增强功能大纲 (相对于 ECMAScript)
  • LLAMAFACTORY:一键优化大型语言模型微调的利器
  • DeepSeek文献太多太杂?一招制胜:学术论文检索的“核心公式”与提问艺术