郑英弥 發表於 2020-7-9 10:36:00

React useEffect

<h1 id="_"></h1>
<blockquote>
<p>今早来又莫名其妙的遇到了 bug,排查了一下是 useEffect 导致的。今天就再来详细的学习一下 react useEffect。</p>
</blockquote>
<h2 id="为什么要">为什么要?</h2>
<blockquote>
<p>我们知道,react 的函数组件里面没有生命周期的,也没有 state,没有 state 可以用 useState 来替代,那么生命周期呢?</p>
</blockquote>
<p>useEffect 是 react v16.8 新引入的特性。我们可以把 useEffect hook 看作是componentDidMount、componentDidUpdate、componentWillUnmounrt三个函数的组合。</p>
<h2 id="详解">详解</h2>
<p>原来我们是这么写 class component</p>
<pre><code class="language-javascript">class LifeCycle extends React.Component {
        constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
}
componentDidMount() {
    document.title = `you clicked me ${this.state.count} times`;
}
componentDidUpdate() {
    document.title = `you clicked me ${this.state.count} times`
}
render() {
    return (
      &lt;div&gt;
      &lt;p&gt;You clicked {this.state.count} times&lt;/p&gt;
      &lt;button onClick={()=&gt; this.setState({count: this.state.count + 1})}&gt;
              Click me
      &lt;/button&gt;
      &lt;/div&gt;
    )
}
}
</code></pre>
<p>现在我们使用 hook 来写 function component</p>
<pre><code class="language-javascript">import React, { useState, useEffect } from 'react';
function Example() {
        const = useState(0);
        useEffect(() =&gt; {
                document.title = `you clicked ${count} times`;
        })
        return (
                &lt;div&gt;
                        &lt;p&gt;You clicked {count} times&lt;/p&gt;
                        &lt;button onClick={() =&gt; setCount(count + 1)}
                                Click me
                        &lt;/button&gt;
                &lt;/div&gt;
        )
}
</code></pre>
<p>上面的这段代码,每次 count 变更以后,effect都会重新执行。</p>
<p>我们日常开发中,获取数据、订阅以及手工更改 React 组件中的 DOM(我之前就更改过)都属于副作用。有些副作用可能需要清除,所以需要返回一个函数,比如设置定时器、清除定时器。</p>
<pre><code class="language-javascript">class Example extends Component {
        constructor(props) {
                super(props);
                this.state = {
                        count: 0;
                }
        }
        componentDidMount() {
                this.id = setInterval(() =&gt; {
                        this.setState({count: this.state.count + 1})
                }, 1000)
        }
        componentWillUnmount() {
                clearInterval(this.id)
        }
        render() {
                return &lt;h1&gt;{this.state.count}&lt;/h1&gt;;
        }
}
</code></pre>
<p>使用 Hook 的示例</p>
<pre><code class="language-javascript">function Example() {
        const = useState(0);
        useEffect(() =&gt; {
                const id = setInterval(() =&gt; {
                        setCount(c =&gt; c + 1);
                }, 1000);
                return () =&gt; clearInterval(id);
        }, []);
        return &lt;h1&gt;{count}&lt;/h1&gt;
}
</code></pre>
<p>我们可以让 React 跳过对 effect 的调用,让 effect 的执行依赖于某个参数(传利数组作为 useEffect 的第二个可选参数就可以了)。倘若仅仅只想执行一次,那么就传递一个空的数组作为第二个参数,这个时候 useEffect hook 不依赖于 props 或者任何值,所以永远都不重复执行。</p>
<p>在过去的性能优化里,在某些情况下,每次渲染后都执行清理或者执行 effect 都可能会导致性能的问题。在 class 组件中,我们通过在 componentDidUpdate 添加 prevProps或者 prevState 来解决。</p>
<pre><code class="language-javascript">componentDidUpdate(prevProps, prevState) {
        if(prevState.count !== this.state.count) {
                document.title = `You clicked ${this.state.count} times`
        }
}
</code></pre>
<p>这个是非常常见的需求。而如今,倘若我们使用 function component,代码会非常的简洁。</p>
<pre><code class="language-javascript">useEffect(() =&gt; {
        document.title = `You clicked ${count} times`;
}, )
</code></pre>
<h2 id="总结">总结</h2>
<p>Hook 是对函数式组件的一次增强,v16.8 出现以后才出来的 hook 特性。在这之前,我看有的代码里面,通过一个&lt;InitialCallBack&gt;来放到函数时组件的最前面,通过在&lt;InitialCallBack&gt;的 componentDidMount 来获取后端接口数据。</p>
<p>就是变相的往 Hook 里面引入生命周期。</p>
<p>然而 v16.8 出来了,这个问题完全解决了。</p>
<p>Hook的语法更简洁易懂,消除了 class 的声明周期方法导致的重复逻辑代码。</p>
<p>同时,在某种程度上解决了高阶组件难以理解和使用的问题。</p>
<p>然而 Hook 并没有让函数时组件做到 class 组件做不到的事情,只是让很多组件变得写的更简单。class 组件不会消失,hook 化的函数时组件将是趋势。</p><br><br>
来源:https://www.cnblogs.com/ssaylo/p/13272166.html
頁: [1]
查看完整版本: React useEffect