在 React 中改变 props 时更新状态
Updating state when props change in React
要在 React 中的 props 发生变化时更新状态:
- 将道具作为依赖项传递给
useEffect
挂钩。 - 每次 props 改变时,里面的逻辑
useEffect
都会重新运行。
应用程序.js
import {useEffect, useState} from 'react'; function Child({parentCount}) { const [childCount, setChildCount] = useState(0); useEffect(() => { setChildCount(parentCount * 2); console.log('useEffect logic ran'); }, [parentCount]); // 👈️ add props as dependencies return ( <div> <button>Child count {childCount}</button> </div> ); } export default function Parent() { const [parentCount, setParentCount] = useState(0); return ( <div> <button onClick={() => setParentCount(current => current + 1)}> Parent count: {parentCount} </button> <hr /> <Child parentCount={parentCount} /> </div> ); }
我们使用useEffect
钩子在 props 改变时更新组件的状态。
应用程序.js
useEffect(() => { setChildCount(parentCount * 2); console.log('useEffect logic ran'); }, [parentCount]); // 👈️ add props as dependencies
useEffect
每当它的依赖项之一发生变化时,挂钩中的逻辑就会重新运行。
每次parentCount
prop 改变时,useEffect
钩子都会重新运行,我们使用该setChildCount
函数来更新状态。
将您要跟踪的所有道具添加到挂钩的依赖项数组中。
useEffect
请注意,我们传递给useEffect
hook 的函数也会在初始渲染时调用。
如果您不想useEffect
在初始渲染时运行挂钩中的逻辑,而只是在特定道具更改时运行,请使用 aref
在初始渲染时尽早返回。
应用程序.js
import {useEffect, useRef, useState} from 'react'; function Child({parentCount}) { const [childCount, setChildCount] = useState(0); const isFirstRender = useRef(true); useEffect(() => { if (isFirstRender.current) { isFirstRender.current = false; return; // 👈️ return early if first render } setChildCount(parentCount * 2); console.log('useEffect logic ran'); }, [parentCount]); return ( <div> <button>Child count {childCount}</button> </div> ); } export default function Parent() { const [parentCount, setParentCount] = useState(0); return ( <div> <button onClick={() => setParentCount(current => current + 1)}> Parent count: {parentCount} </button> <hr /> <Child parentCount={parentCount} /> </div> ); }
当hook 在 mount 上运行时,我们使用ref提前退出。useEffect
如果您想监听道具更改但需要跳过第一次渲染,请使用此方法。
需要注意的是,如果你更新了一个 prop 的值并且这个 prop 出现在钩子的依赖数组中,你会导致无限的重新渲染循环。
这是一个演示此问题的示例。
应用程序.js
import {useEffect, useState} from 'react'; function Child({parentCount, setParentCount}) { useEffect(() => { // 👇️ this causes infinite loop setParentCount(current => current + 1); console.log('useEffect logic ran'); }, [parentCount, setParentCount]); // 👈️ parentCount is a dependency return ( <div> <button>Parent count {parentCount}</button> </div> ); } export default function Parent() { const [parentCount, setParentCount] = useState(0); return ( <div> <Child setParentCount={setParentCount} parentCount={parentCount} /> </div> ); }
问题是我们将parentCount
prop 添加到钩子的依赖项数组中,但我们也在钩子中更新了它的值。
每次useEffect
运行时, 的值parentCount
都会更改,这会再次重新运行挂钩,因为parentCount
它在其依赖项数组中。