React中如何实现计时器组件且不触发其他组件重渲染
解决React/React Native计时器父组件更新导致子组件重复渲染的问题
你的核心问题是父组件中ellapsedSeconds状态每秒更新,触发父组件整体重渲染,进而导致所有子组件(包括ChildComponent)跟着重复渲染。结合你已尝试的方法,这里给出可行的解决方案,同时先修正你代码里的一个小bug:
先修正useEffect的依赖问题
你原代码中useEffect的依赖数组包含ellapsedSeconds,这会导致每秒钟都销毁旧的定时器并创建新的,完全没必要。因为你用了函数式更新setEllapsedSeconds(prev => prev + 1),不需要依赖ellapsedSeconds,把依赖改成空数组即可:
useEffect(() => { const interval = setInterval(() => { setEllapsedSeconds((prevTime) => prevTime + 1); }, 1000); return () => clearInterval(interval); }, []); // 空数组表示只在组件挂载时执行一次
方案一:用React.memo包裹子组件
React.memo会对组件的props进行浅比较,只有当props变化时才会重新渲染组件。你的ChildComponent没有接收任何props,所以用memo包裹后,它只会在组件首次挂载时渲染一次,后续父组件重渲染不会影响它:
const ChildComponent = React.memo(() => { const renderComponent = (): ReactNode => { console.log("现在只会执行一次了!"); // 返回你的组件内容 }; return ( <View> {renderComponent()} </View> ); });
方案二:将计时器文本拆为独立组件+React.memo
如果你希望进一步隔离计时器的重渲染范围,可以把显示时间的逻辑拆成独立组件,这样父组件更新时,只有这个计时器组件会重渲染,其他子组件不受影响(同样需要用memo包裹子组件):
// 独立的时间显示组件 const TimerDisplay = ({ ellapsedSeconds }: { ellapsedSeconds: number }) => { const renderTime = (): string => { const minutes = Math.floor(ellapsedSeconds / 60); const seconds = ellapsedSeconds % 60; return `${minutes < 10 ? `0${minutes}` : minutes}:${ seconds < 10 ? `0${seconds}` : seconds }`; }; return <Text>{renderTime()}</Text>; }; // 父组件 const ParentComponent: React.FunctionComponent = () => { const [ellapsedSeconds, setEllapsedSeconds] = React.useState<number>(0); useEffect(() => { const interval = setInterval(() => { setEllapsedSeconds((prevTime) => prevTime + 1); }, 1000); return () => clearInterval(interval); }, []); return ( <View> <TimerDisplay ellapsedSeconds={ellapsedSeconds} /> <ChildComponent /> </View> ); }; // 用memo包裹子组件 const ChildComponent = React.memo(() => { const renderComponent = (): ReactNode => { console.log("现在只会执行一次了!"); // 返回你的组件内容 }; return ( <View> {renderComponent()} </View> ); });
关于你之前尝试的问题说明
- 拆分组件但父保留状态时,没给子组件加
React.memo,所以父组件重渲染还是会触发子组件的重渲染; useRef存储状态不会触发React的重渲染机制,所以计时器文本无法更新,它适合存储不需要触发UI更新的变量。
内容的提问来源于stack exchange,提问作者Luca
相关产品推荐
相关产品推荐

