04-react组件化开发(父子通信,跨组件通信)

父传子

类组件父传子

 

看似是父类super(props)做了保存,实际上转为es5是子组件自己做的保存

 函数组件父传子

 参数propTypes类型验证

对于父组件传递给子组件的数据,我们希望对数据类型验证,或者进行限制,使用propTypes库

从 React v15.5 开始,React.PropTypes 已移入另一个包中:prop-types 库

对于特别复杂的验证,推荐ts

 

源码相关

子传父

传值应用:react实现slot

我们发现vue有一个非常好用的功能,slot插槽。react没有,因为react更灵活,完全不需要,jsx语法可以向变量一样传递给子组件

方法一:this.props.children(不推荐,需要顺序,一个值时可以使用)

 源码相关

 方法二:把jsx作为变量传递给子组件(推荐,可具名传递)

 context跨组件通信

 相关API

 基本使用

import React, { Component } from 'react'
/* 第一步创建一个context对象,可以给默认值 */
const MyContext =  React.createContext({name:"zhao",age:18})
class Header extends Component{
    render() {
        return(
            <div>
                <span>name:{this.context.name}</span>
                <span>age:{this.context.age}</span>
            </div>
        )
    }
}
/* 第三步,子孙组件宣布使用 */
Header.contextType = MyContext
function Main() {
    return(
        <div>
            <Header/>
            <ul>
                <li>xxxx</li>
                <li>xxxx</li>
            </ul>
        </div>
    )
}
/* 第二步,在父组件中对子孙组件包裹,value中指定给子孙组件的值 */
export default class App extends Component {
    constructor(props) {
        super(props)
        this.state={
            name:"why",
            age:30
        }
    }
    render() {
        return (
            <div>
                <MyContext.Provider value={{...this.state}}>
                    <Main/>
                </MyContext.Provider>
                
            </div>
        )
    }
}

什么时候使用默认值defaultValue呢

当子孙组件没有被context.provider包裹时,子孙组件又订阅了context

 什么时候使用Context.Consumer呢

1.当使用value的组件是一个函数式组件时;

2.当组件中需要使用多个Context时;(嵌套,太恶心了,不想写)

后面多个组件我们使用redux,这个了解就好

事件总线events

import React, { PureComponent } from 'react'

/* 第一步安装yarn add events 导入  导入的是一个类 */
import {EventEmitter} from 'events'
/* 第二步 创建一个 全局事件总线对象 */
const eventBus = new EventEmitter()


export default class App extends PureComponent {
    render() {
        return (
            <div>
                <Home></Home>
                <Goods></Goods>
            </div>
        )
    }
}

class Home extends PureComponent{
    render(){
        return(
            <div>
                <h2>Home</h2>
                <button onClick={e=>{this.onClickBtn()}}>发射事件</button>
            </div>
        )
    }
    onClickBtn(){
        /*第三步 发射事件  第一个参数事件名称,第二个可以为多个参数 放到伪数组args中*/
        eventBus.emit('sayHello','why',18)
    }
}



class Goods extends PureComponent{
   constructor(){
       super()
       this.state = {
           name:"zhao",
           age:22
       }
   }
    render(){
        return(
            <div>
                <h2>Goods</h2>
                <p>{this.state.name}{this.state.age}</p>
                
            </div>
            
        )
    }
    /* 第四步 在生命周期函数中监听 第一个参数要监听事件名称,第二个是回调函数  */
    componentDidMount(){
        eventBus.addListener('sayHello',(name,age)=>{
            this.setState({
                name:name,
                age:age
            })
        })
    }
    /* 不要忘了移除事件监听 */
    componentWillUnmount(){
        eventBus.removeListener('sayHello',(name,age)=>{
            console.log(name,age);
        })
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值