useEffect,函数组件挂载和卸载时触发

1 不带参数

第一次渲染之后和每次更新之后都会执行

<html>

<head>
    <script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>

<body>
    <div id="root"></div>
</body>
<script type="text/babel">
    const e = React.createElement;
    const custom = () => {
      
      
        const [number, setNumber] = React.useState(0);
        React.useEffect(() => {
      
      
            console.log('触发useEffect' + number);
        });
        return <button onClick={
      
      () => setNumber(number + 1)}>点击{
      
      number}</button>
    }
    const domContainer = document.querySelector('#root');
    ReactDOM.render(e(custom), domContainer);
</script>

</html>

每次更新,都会触发useEffect
在这里插入图片描述

2 带参数

可传多个[param1,param2,param3....]
指定参数变化时执行

<html>

<head>
    <script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>

<body>
    <div id="root"></div>
</body>
<script type="text/babel">
    const e = React.createElement;
    const custom = () => {
      
      
        const [number, setNumber] = React.useState(0);
        const [change, setChange] = React.useState(0);
        React.useEffect(() => {
      
      
            console.log('触发useEffect' + number);
        }, [change]);
        return [<button onClick={
      
      () => setNumber(number + 1)}>number{
      
      number}</button>,
        <button onClick={
      
      () => setChange(change + 1)}>change{
      
      change}</button>]
    }
    const domContainer = document.querySelector('#root');
    ReactDOM.render(e(custom), domContainer);
</script>

</html>

只有change更新的时候,才会触发useEffect
在这里插入图片描述

3 传入空数组

只运行一次的 effect(仅在组件挂载和卸载时执行)

<html>

<head>
    <script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>

<body>
    <div id="root"></div>
</body>
<script type="text/babel">
    const e = React.createElement;
    const custom = () => {
      
      
        const [number, setNumber] = React.useState(0);
        React.useEffect(() => {
      
      
            console.log('触发useEffect' + number);
            setNumber(5)
        }, []);
        return <button onClick={
      
      () => setNumber(number + 1)}>点击{
      
      number}</button>
    }
    const domContainer = document.querySelector('#root');
    ReactDOM.render(e(custom), domContainer);
</script>

</html>

(开头刷新了一下)挂载的时候useEffect把number设置为5,之后的更新不触发useEffect
在这里插入图片描述

4 effect返回函数

卸载的时候执行返回函数
用定时器做例子,这是没有返回函数的情况

<html>

<head>
    <script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>

<body>
    <div id="root"></div>
</body>
<script type="text/babel">
    const e = React.createElement;
    const Custom = () => {
      
      
        const [number, setNumber] = React.useState(0);
        React.useEffect(() => {
      
      
            console.log('触发useEffect' + number)
            let interval = null;
            let t = 0
            interval = setInterval(() => {
      
      
                console.log('定时器', t);
                setNumber(++t)
            }, 1000);
        }, []);
        return <div>定时器{
      
      number}</div>
    }
    const customSwitch = () => {
      
      
        const [on, setOn] = React.useState(false);
        return [<button onClick={
      
      () => setOn(!on)}>{
      
      on ? '关闭' : '开启'}</button>,
        on && <Custom />]
    }
    const domContainer = document.querySelector('#root');
    ReactDOM.render(e(customSwitch), domContainer);
</script>

</html>

custom组件卸载的时候,定时器没有取消,重新挂载之后,有了两个定时器
在这里插入图片描述
在返回函数中取消定时器

<html>

<head>
    <script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>

<body>
    <div id="root"></div>
</body>
<script type="text/babel">
    const e = React.createElement;
    let interval = null;
    const Custom = () => {
      
      
        const [number, setNumber] = React.useState(0);
        React.useEffect(() => {
      
      
            console.log('触发useEffect' + number)
            let t = 0
            interval = setInterval(() => {
      
      
                console.log('定时器', t);
                setNumber(++t)
            }, 1000);
            return ()=> {
      
      
                console.log('卸载时触发effect')
                clearInterval(interval)
            }
        }, []);
        return <div>定时器{
      
      number}</div>
    }
    const customSwitch = () => {
      
      
        const [on, setOn] = React.useState(false);
        return [<button onClick={
      
      () => setOn(!on)}>{
      
      on ? '关闭' : '开启'}</button>,
        on && <Custom />]
    }
    const domContainer = document.querySelector('#root');
    ReactDOM.render(e(customSwitch), domContainer);
</script>

</html>

卸载custom的时候,取消定时器,再次挂载的时候,打开定时器。
在这里插入图片描述

官网:https://react.docschina.org/docs/hooks-effect.html
这个写的也挺好的:https://blog.csdn.net/aiwwy/article/details/123338490

猜你喜欢

转载自blog.csdn.net/weixin_43915401/article/details/125065327
今日推荐