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

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

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.kler.cn/a/414015.html

相关文章:

  • (免费送源码)计算机毕业设计原创定制:Java+B/S+SSM+Web前端开发技术+IDEA+MySQL+Navicat 有风小院
  • 【k8s深入理解之 Scheme】全面理解 Scheme 的注册机制、内外部版本、自动转换函数、默认填充函数、Options等机制
  • Flink Sink的使用
  • Edify 3D: Scalable High-Quality 3D Asset Generation
  • MySQL中的like模糊查询
  • 【Linux】线程的互斥和同步
  • 数字IC后端实现之PR工具中如何避免出现一倍filler的缝隙?
  • Binder架构
  • 常见的Web安全漏洞——XSS
  • MySQL中group by实战详细案例笔记
  • 利用dockerCompose一键部署前后端分离项目
  • 大模型时代的具身智能系列专题(十八)
  • [BUUCTF]ciscn_2019_n_8
  • 【YOLO系列复现】二、基于YOLOv6的目标检测:YOLOv6训练自己的数据集(史诗级详细教程)
  • FBX福币交易所固态电池板块逆市掀涨停潮
  • [代码随想录算法01] 704. 二分查找、27. 移除元素、977有序数组的平方
  • mfc110u.dll是什么意思,mfc110u.dll丢失解决方法大全详解
  • 【论文复现】YOLOv5复现
  • [极客大挑战 2019]HardSQL--详细解析
  • matlab显示sin二维图
  • JavaScript对象笔记
  • 跟李笑来学美式俚语(Most Common American Idioms): Part 36
  • std::srand(static_cast<unsigned int>(std::time(0)));每一部分都是啥意思
  • 图数据库 Cypher语言
  • 深度解读sparkRDD宽窄依赖
  • C语言main()函数