用hook模拟生命周期,看这一篇就够辣!

441 阅读2分钟

如今用react开发,绝大多数人肯定用hook来写业务了,我们需要在组件渲染的不同阶段执行一些业务逻辑,这就需要使用类组件的生命周期钩子。那么传统的class组件生命周期怎么用hook来模拟呢?

概要

class组件function组件
constructoruseState
getDerivedStateFromProps更新useState里面的update函数
shouldComponentUpdateReact.memo
render函数本身
componentDidMountuseEffect
componentDidUpdateuseEffect
componentWillUnmountuseEffect里面返回的函数
componentDidCatch
getDerivedStateFromError

关于useEffect中的参数问题

useEffect拥有两个参数,第一个参数作为回调函数会在浏览器布局和绘制完成后调用,因此它不会阻碍浏览器的渲染过程;第二个参数是一个数组。
下面是第二个参数的说明

  • 当数组存在并有值时,如果数组中的任何值发生更改,则每次渲染后都会触发回调;
  • 当它不存在时,每次渲染都会触发回调;
  • 当它是一个空列表时,回调只会被触发一次,类似于componentDidMount;

具体演示

constructor

class foo extends Component {
    constructor() {
        super();
        this.state = {
            num: 0
        }
    }
    render() {
        return <div>{this.state.num}</div>;
    }
}
function foo() {
    const [num, setNum] = useState(0)

    return <div>{num}</div>
}

componentDidMount

class foo extends React.Component {
    componentDidMount() {
        console.log(`componentDidMount`);
    }

    render() {
        return null
    }
}
function foo() {
    useEffect(() => {
        console.log('componentDidMount');
    }, [])
    return null;
}

shouldComponentUpdate

shouldComponentUpdate(nextProps, nextState) {
    console.log(`shouldComponentUpdate`);
    //更新组件
    return true
    //不更新组件
    // return false
}
const MemoComponent = React.memo(
    HeaderComponent,
    (prevProps, nextProps) => nextProps.count !== prevProps.count
)

componentDidUpdate

componentDidUpdate(props, state, snapshot) {
    console.log(`mounted or updated`);
}

useEffect(() => {
    console.log(`mounted or updated`);
})

//如果只想模拟componentDidUpdate,不在组件首次创建时调用,可以使用useRef
const mounted = useRef();

useEffect(() => {
    if (!mounted.current) {
        mounted.current = true;
    } else {
        console.log('didUpdate');
    }
})
//useRef在组件中创建‘实例变量’。作为标志指示组件是否处于挂载或更新阶段。当组件更新完成后会执行else里面的内容,以此来单独模拟componentDidUpdate。

componentWillUnmount

componentWillMount() {
    console.log(`componentWillUnmount`);
}
useEffect(() => {
    return () => {
        console.log(`wilUnmount`);
    }
}, [])

记录记录!