React-3-组件

一、组件基本

1.傻瓜组件和聪明组件

傻瓜组件:也叫做展示组件,根据props显示页面信息。

聪明组件:也叫做容器组件,会在这个组件中进行数据获取,并将数据传递给傻瓜组件。

把这两种组件分离可以分工明确,提高重用性和可读性,便于测试和维护。

2.函数式组件

函数式组件是一种无状态的组件,是为了创建展示组件,这种组件只负责根据传入的props来展示,不涉及到要state状态的操作。

组件不会被实例化,整体渲染性能得到提升。

组件不能访问this。

组件无法访问生命周期方法。

无状态组件只能访问输入的props。

// 这种写法可以将组件暴露给其他地方使用
export default function xxx() {
    return (
        <div></div>
    )
}
// 这种写法只能在当前的js文件中使用
function xxx() {
    return (
        <div></div>
    )
}

3.class组件

import {Component} from 'react'
export default class xxx extends Component () {
    return (
        <div></div>
    )
}

4.条件渲染 

可以通过  a && <b>的方式条件渲染,因为如果a为真则会返回b,如果a为false则会返回a。

5.事件绑定

①在构造函数中用bind绑定事件,这样会导致子组件重新渲染,但是可以传入参数

②定义事件函数为箭头函数,这样不会导致子组件重新渲染,但是不能传递参数,只能接收默认的时间对象e

③定义事件函数为普通函数,但是绑定时通过箭头函数绑定,这样可以兼顾①②的优点。

二、ant-design组件库

1.安装

npm install antd --save 

2.引入

import { Button } from 'antd'

三、性能优化之PureComponent

举个例子:一个容器组件里有两个展示组件,分别是A和B,A传入属性title,B传入属性count,当改变容器的count时,A和B都会重新加载,这样性能就会有问题。

方法一:用shouldComponentUpdate判断一下A传入的属性是否有变化,如果有变化才返回true。

方法二:A组件用PureComponent创建,这样会自动比较该组件传入的参数是否发生了变化,如果发生变化才会更新。

四、性能优化之React.memo

可以让函数式组件也有PureComponent功能

const MemoComponent = React.Memo((props) => {
    return <div>{props.title}</div>
})

五、组件复合写法

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

function Father() {
    const count = 1
    return (
        <Son footer={count}>
            <div>111</div>
            <p>222</p>
        </Son>
    )
}

六、高阶组件(HOC   Hight-Order Component)

1.高阶组件介绍

抽离出具有相同逻辑的组件,其实是一个函数,类似于Python的装饰器,可以给某个组件传入一些额外的参数并重写生命周期。

注意:高阶组件一般以with命名开头(非强制)

import React, { Component } from 'react'

const withLearnReact = (Comp) => {
    const newComponent = (props) => {
        return <Comp {...props} title='小殷'></Comp>
    }
    return newComponent
}

class HOC extends Component {
    render() {
        return (
            <div>
                {this.props.title}  //title就是高阶组件传入的额外参数
            </div>
        )
    }
}
export default withLearnReact(HOC)

2.高阶组件链式调用

高阶组件有两个作用:①添加额外属性  ②重写生命周期

如果只是用于添加属性,则写成函数式就行,但是如果要重写生命周期就需要写成class,链式调用就是分别写两个高阶组件实现以上功能,再进行调用。

import React, { Component } from 'react'

const withLearnReact = (Comp) => {
    const newComponent = (props) => {
        return <Comp {...props} name='小殷'></Comp>
    }
    return newComponent
}
const withLifeCycle = (Comp) => {
    class newComponent extends Component {
        // 重写生命周期
        componentDidMount() {
            console.log("重写了生命周期")
        }

        render() {
            return <Comp {...this.props}></Comp>
        }
    }
    return newComponent
}
class HOC extends Component {
    render() {
        return (
            <div>
                <div>{this.props.title}</div>
                <div>{this.props.name}</div>
            </div>
        )
    }
}
export default withLifeCycle(withLearnReact(HOC))

3.高阶组件装饰器写法

上面的链式调用非常混乱,所以可以用装饰器的写法来简化(ES7)

①安装支持装饰器写法的babel编译插件

②修改配置文件

七、组件通信之上下文context

上下文context有两个角色,provider数据提供,consumer数据读取。

使用context可以避免通过props传递,保存在context中的数据整个组件树都可以使用。

import React, { Component } from 'react'

const store = {
    name: "yin"
}

const Context = React.createContext()
const {Provider, Consumer} = Context

class Context2 extends Component {
    render() {
        return (
            <Consumer>
              {
                  store => {
                    return <div>{store.name}</div>
                  }
              }
            </Consumer>
        )
    }
}

function Middle() {
  return <Context2></Context2>
}

export default class Context1 extends Component {
    render() {
        return (
            <Provider value={store}>
                <Middle></Middle>
            </Provider>
        )
    }
}
原文地址:https://www.cnblogs.com/yinwenjie/p/12239357.html