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

React 第九节 组件之间通讯之props 和回调函数

组件之间通讯常用方案
1、通过props
2、通过context
3、通过发布订阅模式
4、通过Redux 后面会有专栏介绍

1、父组件向子组件通过 props 进行通讯

首先请先了解组件的三大属性之 props
补充以下内容,基于函数式组件

1.1、单个属性传递

// 父组件
import { useState } from 'react'
// 引入 ChildA 组件
import ChildA from './childA'
export default function MyComP() {const [name, setName] = useState('Andy')const [age, setAge] = useState(18)const [students, setStudents] = useState([])return (<><h2>父组件</h2>{/* 单个属性传递 */}<ChildA name={name} age={age}></ChildA></>)
}
// 子组件
export default function ChildA(props) {console.log('==data==', props)// 若子组件需要对传入的 props 数据进行再次加工,类似 VUE 中写法,需要使用新的变量接住 props的属性,比如自身名称 需要在父组件名称基础上 +1,如:const [selfName, setSelfName] = useState(props.name)const handleChangeSelfName = () => {setSelfName(`${selfName}+1`)}return (<><h3>childA组件:</h3>{/* 子组件中如果不需要 对props 传递进来的值进行二次加工,则直接展示使用即可 */}<p>操作人员:{props?.name ?? '--'}</p> <p>年龄:{props?.age ?? '--'}</p> <p>子组件自身名称:{setSelfName}</p><button onClick={handleChangeSelfName}>修改自身名称</button></>)
}

1.2、多个属性 对象、数组 进行传递

// 父组件
import { useState } from 'react'
import ChildA from './childA'
export default function MyComP() {const [students, setStudents] = useState([{name: '张三', age:18},{name: '李四', age: 19},{name: '王五', age: 20},])const [useInfo, setUseInfo] = useState({name: 'Andy',age: 18,gender: '男',address: '郑州',})return (<><h2>父组件</h2>{/* 通过扩展运算符,或者将整个数组对象传给子组件 */}<ChildA students={students} useInfo={{...useInfo}}></ChildA></>)
}
// 子组件
import {useState} from 'react'export default function ChildA(props) {console.log('==data==', props)return (<><h3>学生信息:</h3><ul>{props.students.map((student, index) =>{return(<li key={index}><p>姓名:{student.name}</p><p>年龄:{student.age}</p></li>)})}</ul></>)
}

1.3、函数式组件中 默认值的写法

通过 defaultProps 设置默认值

这种方式赋默认值,在函数式组件,类式组件中都适用

    import React from 'react'export default function ChildB(props) {return (<><h2>子组件B</h2><p>年龄:{props?.age ?? '--'}</p> <p>子组件操作人员:{props?.name ?? '--'}</p></>)}ChildB.defaultProps = {name: 'ChildB', // 设置默认名称与年龄age: 20,}

在函数式组件中直接给参数添加默认值

这种形式 只适合 函数式组件,并且对于多个参数需要赋默认值的行为,不太友好;

import React from 'react'
export default function ChildB({name='ChildB', age=23}) {return (<><h2>子组件B</h2><p>年龄:{age ?? '--'}</p> <p>子组件操作人员:{name ?? '--'}</p></>)
}

1.4、父组件 通过children 属性 向子组件传 对象 dom结构

知道有这么回事就行,不建议使用,削减了组件的健壮性,
类似vue中插槽的作用

```javascript
// 父组件
import { useState, useRef, useEffect } from 'react'import ChildB from './childB'
export default function MyComP() {const [name, setName] = useState('Andy')const [useInfo, setUseInfo] = useState({name: 'Andy',age: 18,gender: '男',address: '郑州',})const handleChangNaem = (newName) => {setName(newName)}const handleChangeRef = () => {console.log('---myComRef-',)}return (<><h2>父组件</h2><ChildB onChangName={handleChangNaem} name={name} >{/* 可以传递多种类型,多个节点 */}{/* 向子组件传递额外属性 */}{{...useInfo}}{/* 向子组件传递 dom结构 */}<span>children 数据</span></ChildB></>)
}```

子组件接收 props 的children属性,children是一个数组

```javascript
export default function ChildB({name, onChangName, children}) {console.log('===children=', children)const [text, setText] = useState('')const handleChangNaem = () => {console.log('修改名称')onChangName('Andy222') // 假设修改名称}
return (<div><h2>子组件B</h2><p>子组件操作人员:{name ?? '--'}</p><button onClick={handleChangNaem}>修改名称</button><p>用户信息{children[0].name}</p><p>{children[1]}</p></div>
)
}
```

children 是一个数组,可以通过数组的 map、forEach 方法进行遍历;
父组件传递的数据可以是 基本类型变量、引用类型变量、DOM结构、还可以是函数

注意空节点(null,undefined 以及布尔值),字符串数字和 React 元素 都会被统计为单个节点。在遍历统计的过程中,React 元素不会被渲染,所以其子节点不会被统计。Fragment 也不会被统计

2、子组件通过回调函数向父组件传值

// 父组件
import { useState } from 'react'
import ChildB from './childB'
export default function MyComP() {const [name, setName] = useState('Andy')const [age, setAge] = useState('18')const handleChangNaem = (newName) => {setName(newName)}return (<><h2>父组件</h2>{/* 父组件 通过 onChangName 函数接收 子组件传递参数 */}<ChildB onChangName={handleChangNaem} name={name}></ChildB></>)
}
// 子组件 通过onChangeName 给父组件传递新名称
export default function ChildB({name='ChildB', age=23, onChangName}) {const handleChangNaem = () => {console.log('修改名称')onChangName('Andy222') // 假设修改名称}return (<><h2>子组件B</h2><p>年龄:{age ?? '--'}</p> <p>子组件操作人员:{name ?? '--'}</p><button onClick={handleChangNaem}>修改名称</button></>)
}

http://www.mrgr.cn/news/79052.html

相关文章:

  • Lua面向对象实现
  • C语言实例_22之计算阶乘n!
  • 【C++】动态内存(六)——动态数组
  • Observability:如何在 Kubernetes pod 中轻松添加应用程序监控
  • 【大数据学习 | Spark调优篇】Spark之内存调优
  • Excel如何限制单元格内可选择的下拉框内容?
  • 重生之我在异世界学编程之C语言:深入指针篇(上)
  • 组合问题变式——选数(dfs)
  • 嵌入式硬件面试题【经验】总结----会不断添加更新
  • IDL学习笔记(二)IDL处理卫星数据
  • 使用playwright自动化测试时,npx playwright test --ui打开图形化界面时报错
  • L15.【LeetCode笔记】相同的树
  • 同时将scss全局变量注入、Tailwind样式使用、自己插件配置到vite
  • 汽车IVI中控OS Linux driver开发实操(二十七):常用Linux指令
  • 记录vite关于tailwindcss4.0-bate4出现margin[m-*]、padding[p-*]无法生效的问题。
  • 神经网络中的优化方法(一)
  • Android 应用单元测试涉及 Telephony 环境初始化问题
  • 浏览器的事件循环机制
  • 深入解析 Dubbo 中的常见问题及优化方案: 数据量限制与配置错误20241203
  • 嵌入式系统应用-LVGL的应用-平衡球游戏 part1
  • 三维地形图计算软件(四)-用PYQT5+vtk画任意多面体示例
  • 澎峰科技助力中国移动 重磅发布智算“芯合”算力原生基础软件栈2.0
  • 网络安全-夜神模拟器如何通过虚拟机的Burp Suite代理应用程序接口
  • 3GPP R18 LTM(L1/L2 Triggered Mobility)是什么鬼?(三) RACH-less LTM cell switch
  • PROTEUS资源导引
  • flask的第一个应用