Front-end/react/6.组件生命周期.md

7.6 KiB
Raw Permalink Blame History

只有类组件才有生命周期

  1. 创建
class LifeCreate extends React.Component{
    constructor(props){
        super(props)
        console.warn('1.生命周期钩子函数constructor')
    }
    componentDidMount(){
        console.warn('3.生命周期钩子函数componentDidMount')
    }
    render(){
        console.warn('2.生命周期钩子函数render')
        return (<div><h3>hello</h3></div>)
    }
}
  1. 更新 New props,setState,forceUpdate
class LifeUpdate extends React.Component{
    constructor(props){
        super(props)
        console.warn('1.生命周期钩子函数constructor')
        this.state = {
            count:0
        }
    }
    componentDidMount(){
        console.log(document.getElementById('root'))
        console.warn('3.生命周期钩子函数componentDidMount')
    }
    handlerClick= ()=>{
        // this.setState({
        //     count:this.state.count+1
        // })
        this.forceUpdate()
    }
    render(){
        console.warn('2.生命周期钩子函数render')
        return (<div><Counter count = {this.state.count}/><button onClick={this.handlerClick}>hello</button></div>)
    }
}
class Counter extends React.Component{
    componentDidUpdate(prevProps){
        console.warn('---------------生命周期钩子函数componentDidUpdate')
        if(prevProps.count!=this.props.count){
            this.setState({})
        }
    }
    render(){
        console.warn('---------------生命周期钩子函数render')
        return (<p>点击次数{this.props.count}</p>)
    }
}
  1. 卸载
class LifeEnd extends React.Component{
    constructor(props){
        super(props)
        console.warn('1.生命周期钩子函数constructor')
        this.state = {
            count:0
        }
    }
    componentDidMount(){
        console.log(document.getElementById('root'))
        console.warn('3.生命周期钩子函数componentDidMount')
    }
    handlerClick= ()=>{
        this.setState({
            count:this.state.count+1
        })
        // this.forceUpdate()
    }
    render(){
        console.warn('2.生命周期钩子函数render')
        return (<div>
            {this.state.count>3?("goodby"):<Counter count = {this.state.count}/>}
            <button onClick={this.handlerClick}>hello</button></div>)
    }
}
class Counter extends React.Component{
    componentDidUpdate(prevProps){
        console.warn('---------------生命周期钩子函数componentDidUpdate')

        if(prevProps.count!==this.props.count){
            this.setState({})
        }
    }
    componentDidMount(){
        this.timerId = setInterval(()=>{
            console.log("定时器在执行")
        },500)
    }
    componentWillUnmount(){
        clearInterval(this.timerId)
        console.warn("结束")
    }
    render(){
        console.warn('---------------生命周期钩子函数render')
        return (<p>点击次数{this.props.count}</p>)
    }
}

组件复用

复用组件的状态逻辑1.state2.操作state的方法.

render props

将要复用的state和操作state的方法封装到一个组件中 添加一个值为函数的prop,通过函数参数来获取(需要组件内部来实现) 使用该函数的返回值,作为要渲染的UI内容

import img from './img/20200205205324.jpg'
import PropTypes from "prop-types"
class RepeatUse extends React.Component {
    render(){
        return (
            <div>
                <h1>render props 复用模式</h1>
                <Mouse >{mouse=>{return (<p>X:{mouse.x},Y{mouse.y}</p>)}}</Mouse>
                <Mouse >{mouse=>{return <img src={img} alt="" style={{position:'absolute',top:mouse.y-350,left:mouse.x-350}} />}}</Mouse>
            </div>
        )
    }
}
class Mouse extends React.Component {
    state = {
        x: 0, y: 0
    }
    handleMouseMove = e => {
        this.setState({
            x: e.clientX,
            y: e.clientY
        })
    }
    // 监听鼠标移动
    componentDidMount() {
        window.addEventListener('mousemove', this.handleMouseMove)
    }
    componentWillUnmount(){
        window.removeEventListener('mousemove', this.handleMouseMove)
    }
    render(){
        return this.props.children(this.state)
    }
}
Mouse.propTypes={
    children:PropTypes.func.isRequired
}

高阶组件HOC

是一个函数,接收要包装的组件,返回增强后的组件

  1. 创建函数以with开头
  2. 指定函数参数,参数大写开头
  3. 函数内部创建类组件,提供复用状态逻辑代码
  4. 在组件中渲染参数组件,同时通过prop传递给参数组件(high order component)
  5. 调用高阶组件,传入要增强的组件,通过返回值拿到增强后的组件并将其渲染到页面.
class RepeatUse extends React.Component {
    render(){
        return (
            <div>
                <h1>render props 复用模式</h1>
                <MoousePosition ></MoousePosition>
            </div>
        )
    }
}

function withMouse(WrappedComponent){
    class Mouse extends React.Component {
        state = {
            x: 0, y: 0
        }
        handleMouseMove = e => {
            this.setState({
                x: e.clientX,
                y: e.clientY
            })
        }
        // 监听鼠标移动
        componentDidMount() {
            window.addEventListener('mousemove', this.handleMouseMove)
        }
        componentWillUnmount(){
            window.removeEventListener('mousemove', this.handleMouseMove)
        }
        render(){
            // return this.props.children(this.state)
            return <WrappedComponent {...this.state}></WrappedComponent>
        }
    }
    
    return Mouse
}

const Position = props=>(
    <p>
        鼠标当前位置(x:{props.x},y:{props.y})
    </p>
)
const MoousePosition = withMouse(Position)

设置displayName便于区分

class RepeatUse extends React.Component {
    render(){
        return (
            <div>
                <h1>render props 复用模式</h1>
                <MoousePosition ></MoousePosition>
                {/* <MoousePosition >{mouse=>{return (<p>X:{mouse.x},Y{mouse.y}</p>)}}</MoousePosition> */}
                {/* <MoousePosition >{mouse=>{return <img src={img} alt="" style={{position:'absolute',top:mouse.y-350,left:mouse.x-350}} />}}</MoousePosition> */}
            </div>
        )
    }
}

function getDisplayName(WrappedComponent){
    return WrappedComponent.displayName || WrappedComponent.name || 'Component'
}

function withMouse(WrappedComponent){

    class Mouse extends React.Component {
        state = {
            x: 0, y: 0
        }
        handleMouseMove = e => {
            this.setState({
                x: e.clientX,
                y: e.clientY
            })
        }
        // 监听鼠标移动,仅挂载执行一次
        componentDidMount() {
            window.addEventListener('mousemove', this.handleMouseMove)
        }
        componentWillUnmount(){
            window.removeEventListener('mousemove', this.handleMouseMove)
        }
        render(){
            // return this.props.children(this.state)
            return <WrappedComponent {...this.state}></WrappedComponent>
        }
    }
    // 设置展示名称
    Mouse.displayName = `WithMouse${getDisplayName(WrappedComponent)}`
    return Mouse
}

const Position = props=>(
    <p>
        鼠标当前位置(x:{props.x},y:{props.y})
    </p>
)
const MoousePosition = withMouse(Position)

高阶组件传递 props

        render(){
            // return this.props.children(this.state)
            return <WrappedComponent {...this.state}{...this.props}></WrappedComponent>
        }

组件极简模型

(state,props)=>UI