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

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

首先请先了解组件的三大属性之 props

补充以下内容,基于函数式组件

1.1、单个属性传递

javascript 复制代码
// 父组件
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>
        </>
    )
}
javascript 复制代码
// 子组件
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、多个属性 对象、数组 进行传递

javascript 复制代码
// 父组件
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>
        </>
    )
}
javascript 复制代码
// 子组件
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 设置默认值

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

javascript 复制代码
    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,
    }

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

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

javascript 复制代码
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、子组件通过回调函数向父组件传值

javascript 复制代码
// 父组件
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>
        </>
    )
}
javascript 复制代码
// 子组件 通过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>
    </>
  )
}
相关推荐
我命由我123456 分钟前
Dart - Dart SDK、Hello World 案例、变量声明、常量声明、常量 final、字符串类型
前端·flutter·前端框架·html·web·dart·web app
冴羽yayujs9 分钟前
GitHub 前端热榜项目 - 日榜(2026-05-11)
前端·github
~|Bernard|9 分钟前
四,go语言中GMP调度模型
java·前端·golang
YOU OU17 分钟前
HTML+CSS+JavaScript
前端·javascript·css·html
Rkgua34 分钟前
路径传参和查询传参和请求体传参区以及Vue和React的用法区分
前端·面试
JarvanMo34 分钟前
Flutter + Supabase 集成 Apple Sign-In 完整指南
前端
小村儿1 小时前
连载
前端·后端·ai编程
dinl_vin1 小时前
LangChain 系列·(九):Agent——让 AI 自己做决策
前端·人工智能·langchain
孟祥_成都1 小时前
前端唯一的护城河?结合 AI 将字节组件库 Headless 化后的感想~
前端·人工智能·react.js
尽欢i1 小时前
前端大坑!文件切片上传后端总报错找不到文件名?
前端·javascript