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>
    </>
  )
}
相关推荐
GISer_Jing18 分钟前
React前端面试题详解(一)
前端·react.js·前端框架
呵呵哒( ̄▽ ̄)"19 分钟前
React 实战选择互动特效小功能
前端·javascript·react.js
Python私教23 分钟前
Docker化部署Django:高效、可扩展的Web应用部署策略
前端·docker·django
YiSLWLL26 分钟前
Django+Nginx+uwsgi网站Channels+redis+daphne多人在线聊天实现粘贴上传图片
javascript·python·nginx·django
查拉图斯特拉面条41 分钟前
前端页面元素定位与XPath优化
前端·ui·自动化
大今野1 小时前
JavaScript的let、var、const
开发语言·javascript·ecmascript
刺客-Andy1 小时前
React第十节组件之间传值之context
前端·javascript·react.js
顾北川_野1 小时前
Android 12.0 通知--PendingIntent基本代码
java·前端·javascript
C.果栗子1 小时前
前端页面或弹窗在线预览文件的N种方式
前端
Master_清欢1 小时前
防止按钮被频繁点击
开发语言·前端·javascript