You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 13:23:11