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> ) } }