使 React useEffect 钩子不在初始渲染上运行 [英] Make React useEffect hook not run on initial render
问题描述
根据文档:
<块引用>componentDidUpdate()
在更新发生后立即调用.初始渲染不会调用此方法.
我们可以使用新的 useEffect()
钩子来模拟 componentDidUpdate()
,但看起来 useEffect()
正在被运行每次渲染,即使是第一次.如何让它不在初始渲染中运行?
正如您在下面的示例中看到的,componentDidUpdateFunction
在初始渲染期间打印,但 componentDidUpdateClass
在初始渲染期间未打印.
function ComponentDidUpdateFunction() {const [count, setCount] = React.useState(0);React.useEffect(() => {console.log("componentDidUpdateFunction");});返回 (<div><p>componentDidUpdateFunction: {count} 次</p><按钮onClick={() =>{设置计数(计数 + 1);}}>点击我按钮>
);}class ComponentDidUpdateClass 扩展 React.Component {构造函数(道具){超级(道具);this.state = {计数:0,};}componentDidUpdate() {console.log("componentDidUpdateClass");}使成为() {返回 (<div><p>componentDidUpdateClass:{this.state.count} 次</p><按钮onClick={() =>{this.setState({ 计数: this.state.count + 1 });}}>点击我按钮>
);}}ReactDOM.render(<div><ComponentDidUpdateFunction/><ComponentDidUpdateClass/>
,document.querySelector("#app"));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script><script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script><div id="app"></div>
我们可以使用 useRef
钩子来存储我们喜欢的任何可变值,所以我们可以使用它来跟踪 useEffect 是否是第一次
函数正在运行.
如果我们希望效果在 componentDidUpdate
执行的相同阶段运行,我们可以使用 useLayoutEffect
代替.
示例
const { useState, useRef, useLayoutEffect } = React;函数 ComponentDidUpdateFunction() {const [count, setCount] = useState(0);const firstUpdate = useRef(true);useLayoutEffect(() => {如果(firstUpdate.current){firstUpdate.current = false;返回;}console.log("componentDidUpdateFunction");});返回 (<div><p>componentDidUpdateFunction: {count} 次</p><按钮onClick={() =>{设置计数(计数 + 1);}}>点击我按钮>
);}ReactDOM.render(<ComponentDidUpdateFunction/>,document.getElementById("app"));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script><script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script><div id="app"></div>