React组件

划分根据:是否拥有自己的state以及创建方式。通过类创建的组件一般是复杂组件,通过函数创建的组件一定是简单组件。通过类创建的组件继承了Component,从而拥有了Component的生命周期和特性。所有被称为复杂组件

2-1:特点:

  • 函数组件写法简洁,承担的责任明确,本质是一个函数,接受一个外部传入的props,返回对应的UI描述
  • 类组件功能更加强大,继承了React.component,拥有自己的生命周期以及一些钩子函数,方便在不同阶段对组件进行操作,对组件进行更多的控制
  • 有状态组件能使用this ,无状态组件不能使用this

2-2:使用时机

如果想要存储一些数据并且想要对这些数据进行增删改查 那么就应该使用有状态组件,如果只是单纯的处理一些逻辑就用无状态组件。我们更多的应该是使用无状态组件(因为如果一个是有状态组件的话那么他就会触发一些生命周期定义的函数。一旦触发这些函数就会影响当前项目的运行,所以尽可能使用无状态组件,除非对当前组件不是很清晰是否要储存数据的时候选择有状态组件)状态的东西都会通过父级去传递,比如Persons,Header这些组件如果想用到数据的话我们可以通过传参的形式给它传递过去,即当前的数据能够进行统一的数据管理,比如说通过父级管理数据,其他组件如果想拥有这个组件的话可以通过传值的形式给它。

2-3:组件通讯

2-3-1:父向子通讯

父组件通过props向子组件传递props,子组件的到props

function Father(props){
    let name = "父组件值"
    return(
    	<Son name={name}></Son>
    )
}

function Son(props){
    return(
    	<div>{props.name}</div>
	)
}

2-3-2:子向父

利用回调函数,可以实现子组件向父组件通信,父组件一个函数作为props传递给子组件,子组件调用该回调函数,便可以向父组件通信

class Father extends Component{
    callback(meg){
        console.log(msg)
    }
    render(){
        return(
        	<Son callback={this.callback.bind(this)}></Son>
        )
    }
}

function Son(props){
    let name = "son name"
    return(
    	<div onclick={props.callback(name)}>{props.name}</div>
	)
}

2-3-2:跨级组件通信

跨级组件通讯:父组件向更深层次组件通讯,,一般有两种方式中间组件层层传递props 使用context对象 对于第一种方式,如果结构层次较深,明显增加了复杂程度,适用于三层以内的结构,当组件层次较深时,就需要采用context,设置context,则这个结构树的所有组件都可以共享这个context,但是如果内部出现context,则就近选择context,使用方法

2-3-4:非嵌套组件通讯

非嵌套组件,就是没有任何包含关系的组件,包括兄弟组件以及不在同一个父级中的非兄弟组件。对于非嵌套组件,可以采用下面两种方式:

  • 利用二者共同父组件的context对象通讯
  • 使用自定义事件通讯

如果采用组件共同的父级进行中转,会增加组件之间的耦合(推荐高内聚,低耦合),如果组件层次较深的话,不易找到公共父组件,这个时候我们就需要采用自定义事件的方式来实现非嵌套组件间的通讯

1:我们需要要给events包

npm install events

2:新建一个ev.js引入events包,并向外提供一个事件对象,供通讯使用,自定义事件是典型的发布/订阅模式,通过向事件对象上添加监听器和触发事件来实现组件间通信。

//ev.js
import {EventEmitter} from "events"
export default new EventEmitter();
//app.js
import React from 'react'
import Foo form './Foo'
import Boo form './Boo'
class App extends React.component{
    constructor(){
        this.state = {
        	msg:""
        }
    }
    render(){
        return(
        	<>
            	<Foo/>
            	<Boo/>
            </>
        )
    }
}
//Foo.js
import React,{ Component } from "react";
import emitter from "./ev"

export default class Foo extends Component{
    constructor(props) {
        super(props);
        this.state = {
            msg:null,
        };
    }
    componentDidMount(){
        // 声明一个自定义事件,在组件装载完成以后
        this.eventEmitter = emitter.addListener("callMe",(msg)=>{
            this.setState({
                msg
            })
        });
    }
    // 组件销毁前移除事件监听
    componentWillUnmount(){
        emitter.removeListener(this.eventEmitter);
    }
    render(){
        return(
            <div>
                { this.state.msg }
                我是非嵌套 1 号
            </div>
        );
    }
}
//Boo.js
import emitter from "./ev"
export default class Boo extends Component{
    render(){
        const cb = (msg) => {
            return () => {
                // 触发自定义事件
                emitter.emit("callMe","Hello")
            }
        }
        return(
            <div>
                我是非嵌套 2 号
                <button onClick = { cb("blue") }>点击我</button>
            </div>
        );
    }
}

2-3:高阶组件

以参数为组件,返回值为新的组件,组件时将props转化为UI,高阶组件是将一个组件转换为另一个组件

posted @ 2020-11-02 15:23  Yanzq-X  阅读(65)  评论(0)    收藏  举报