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
相关产品推荐
相关产品推荐

