React-学习笔记(7-组件间通信的几种方式)

目录

1、父组件向子组件传递数据(Props)

2、子组件向父组件传递数据

3、任意组件间通信(消息订阅与发布)


1、父组件向子组件传递数据(Props)

        父组件:

import React, { Component } from 'react'

// 引入子组件
import Children from '../Children/Children'

export default class Parent extends Component {
    render() {
        let curTime = new Date().toLocaleDateString();
        curTime = curTime.replaceAll('/',' - ');
        return (
            <div>
                {/* 展示子组件,给子组件传递一个数据 */}
                <Children curTime={curTime}/>
            </div>
        )
    }
}

        下载 prop-types,给 props 添加约束:

npm i prop-types
import React, { Component } from 'react'
// 引入 prop-types
import propTypes from 'prop-types'

export default class Children extends Component {
    // 配置 props 约束
    static propTypes = {
        // 字符串类型,必须
        // curTime:propTypes.string.isRequired       // 这样写,即使是空字符串也满足

        // 自定义校验方式,第一个参数为一整个props对象,第二个参数为当前约束属性名,第三个对象为当前组件名
        curTime:(prop, propName, componentName)=>{
            // 当父组件Parent传递字符串为:2023 - 4 - 26 时,输出为 
            // Object:{curTime:'2023 - 4 - 26'}  curTime  Children
            console.log(prop,propName,componentName);
            
            let temp = prop[propName].split('-');
            if(temp.length !== 3){              // 简单的用拆分字符串的形式来检查一下
                return new Error('格式错误');    // 校验不通过需要返回一个错误对象,会在控制台中打印
                // 即使不通过,返回了一个错误对象,该不满足要求的数据仍然会展示到页面对应位置中
            }
        }
    }

    render() {
        // 从父组件中接收到指定的数据
        const {curTime} = this.props;
        return (
            <div>
                <h1 style={
   
   {color:'red',fontWeight:600}}>时间:{curTime}</h1>
            </div>
        )
    }
}

2、子组件向父组件传递数据

        需要父组件提前定义一个函数,然后该函数需要的参数就是子组件向父组件传的数据,函数体的内容可以是在父组件中处理该参数(子组件传过来的数据),也可以把数据传给其他的子组件实现兄弟组件之间的通信等。

扫描二维码关注公众号,回复: 16473228 查看本文章

        子组件 Children,用于提供用户输入环境。

import React, { Component } from 'react'

// 提供输入框让用户输入内容,并利用父组件给的函数,将数据传给父组件
export default class Children extends Component {
    state = {
        inpVal:''
    }
    collectData(e){
        // 更新身上的属性
        this.setState({
            inpVal:e.target.value
        })

        // 调用父组件给的函数,将数据传递过去
        this.props.sendData(e.target.value);

        // this.setState 是异步方法 故不能写成以下的形式
        // this.props.sendData(this.state.inpVal);
    }
    render() {
        return (
            <div style={
   
   {border:'1px solid orange',padding:'5px 10px'}}>
                <input type="text" onChange={(event)=>(this.collectData(event))}/>
            </div>
        )
    }
}

        子组件 Children_a 用于实时展示用户输入的内容。

import React, { Component } from 'react'

// 实时展示用户输入的内容
export default class Children2 extends Component {
    render() {
        return (
            <div style={
   
   {border:'1px solid green',padding:'5px 10px',minHeight:'40px'}}>
                <div>{this.props.content}</div>
            </div>
        )
    }
}

        父组件 Parent。接收到 Children 组件中用户输入的数据,将该数据传给 Children_a。

import React, { Component } from 'react'

// 引入两个子组件
import Children from '../Children/Children';
import Children_a from '../Children_a/Children_a'

export default class Parent extends Component {
    state = {
        data:''
    }
    render() {
        return (
            <div>
                {/* 该函数实时修改 state 中对应的数据,当state更新,重新调用render */}
                <Children sendData={(data)=>{
                    this.setState({
                        data
                    })
                }}/>

                <Children_a content={this.state.data}/>
            </div>
        )
    }
}

3、任意组件间通信(消息订阅与发布)

        使用 PubSub-js 库。安装:

npm i pubsub-js

        在项目中引入:

import PubSub from 'pubsub-js'

        三个主要的函数:

1、PubSub.subscribe('订阅消息名', 处理函数);        —— 订阅消息

2、PubSub.unsubscribe('取消订阅的消息名');   —— 取消订阅

3、PubSub.publish('消息名', 数据);—— 发布消息

        组件 InputArea ,用于提供用户输入环境,并实时发布消息,传递用户输入的完整内容作为消息的数据。

import React, { Component } from 'react'
// 引入消息订阅与发布库
import PubSub from 'pubsub-js'
// 引入对应的Scss样式文件
import './InputArea.scss'

// 受控组件,实时监听 input 的改变,并实时发布指定的消息
export default class InputArea extends Component {
    inpval = React.createRef();
    inputHandler = ()=>{
        // 发布 showDate 类的消息,传递此时输入框中的内容作为参数
        PubSub.publish('showData',this.inpval.current.value);
    }
    render() {
        return (
            <div>
                <input ref={this.inpval} type="text" className='inp'
                    onChange={this.inputHandler} placeholder='请输入随意内容,将展示到下方区域'/>
            </div>
        )
    }
}

        组件 CollectInput 。订阅用户输入的消息,将用户输入的数据实时更新到面板中。

import React, { Component } from 'react'
// 引入消息订阅与发布库
import PubSub from 'pubsub-js'
// 引入对应的Scss样式文件
import './CollectInput.scss'

export default class CollectInput extends Component {
    state = {
        receiveData:''
    }
    componentDidMount(){
        // 当前组件定阅 showData 类的消息
        PubSub.subscribe('showData',(msg,data)=>{
            // 当接收到新的消息时,执行此回调函数,改变 state 中的 receiveData
            this.setState({receiveData:data});
        })
    }
    // 在组件即将要被卸载时,取消订阅所有订阅过的消息
    componentWillUnmount(){
        PubSub.unsubscribe('showData');
    }
    render() {
        return (
            <div className='container'>
                <p className='passage'>{this.state.receiveData}</p>
            </div>
        )
    }
}

        在 App 组件中使用这两个组件:

import React from 'react';

import InputArea from './components/InputArea/InputArea'
import CollectInput from './components/CollectInput/CollectInput'


export default class App extends React.Component{
    render(){
        return(
            <div>
                <InputArea/>
                <CollectInput/>
            </div>
        )
    }
}

猜你喜欢

转载自blog.csdn.net/hao_13/article/details/130383538