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

React中修改Context状态时如何避免组件不必要刷新?

React TikTok克隆项目:全局静音状态触发滚动重置问题

我正在做TikTok克隆项目作为React入门实践,需要实现一个全局的isVideoMuted状态,切换该状态时能一键静音/取消静音所有视频。但当前功能存在问题:当从子组件修改ContextProvider中的状态时,React会重新渲染所有组件,导致页面的垂直滚动进度直接重置到顶部。

相关代码

VideoContextProvider.tsx

const VideoContextProvider = ({ children }: any) => {
  const [isVideoMuted, setIsVideoMuted] = useState(true);
  const [videos, setVideos] = useState([] as Video[]);

  return (
    <VideoContext.Provider
      value={{
        videos,
        setVideos,
        isVideoMuted,
        setIsVideoMuted,
      }}
    >
      {children}
    </VideoContext.Provider>
  );
};

VideoCard.tsx

const VideoCard: FC<Props> = ({ video }) => {
  const router = useRouter();

  const [isLiked, setIsLiked] = useState(false);
  const [isVideoPlaying, setIsVideoPlaying] = useState(false);

  const { isVideoMuted, setIsVideoMuted } = useContext(VideoContext);
  
  return (
    // 视频相关代码,包含<video>元素
    <Box p="xs">
      {isVideoMuted ? (
        <VscMute
          fontSize="28px"
          color="white"
          onClick={() => setIsVideoMuted(false)}
        />
      ) : (
        <VscUnmute
          fontSize="28px"
          color="white"
          onClick={() => setIsVideoMuted(true)}
        />
      )}
    </Box>
    // 其他组件代码
  );
};

export default VideoCard;
// export const VideoCardMemoized = memo(VideoCard);

已尝试的解决方法

  • 创建VideoCard的memoized版本并使用,但组件仍然会刷新
  • 将const { isVideoMuted, setIsVideoMuted } = useContext(VideoContext);移至独立的VideoSidebar组件,但因为视频元素需要订阅isVideoMuted变量,问题依旧存在

内容的提问来源于stack exchange,提问作者Pοlatic

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 02:35:19