gpt4 book ai didi

javascript - 使用 mapbox 和 react context 时防止过度重新渲染

转载 作者:行者123 更新时间:2023-12-05 04:38:35 27 4
gpt4 key购买 nike

我有一个使用 mapbox map 的应用程序,我试图允许从另一个单独的卡片组件调整视口(viewport)。我采用的方法是创建视口(viewport)上下文并将视口(viewport)和将其设置为 map 和卡片组件的函数。

这可行,但我遇到了重新渲染的问题。每当用户在 map 上滚动时,视口(viewport)都会不断变化,因此视口(viewport)提供程序中的所有内容都会不断重新渲染。下面是代码的简化版本

应用

<ViewportProvider>
*Container that holds both the map and the sidebar that renders the card components*
</ViewportProvider>

视口(viewport)提供者

import React from "react";
const INITIAL_STATE = {
longitude: 15,
latitude: 25,
zoom: 1

};

export const ViewportContext = React.createContext();

export const ViewportProvider = (props) => {
const [viewport, setViewport] = React.useState(INITIAL_STATE);


return (
<ViewportContext.Provider
value={{
viewport,
setViewport,
}}
{...props}
/>
);
}

map

import React, { useContext } from "react";
import ReactMapGL from "react-map-gl";
import { ViewportContext } from "./ViewportProvider";

const { viewport, setViewport } = useContext(ViewportContext);

<Map onViewportChange={nextViewport => setViewport(nextViewport)} {...viewport}/>

卡片

const {setViewport} = useContext(ViewportContext)

<Card onClick={setViewport(...newValue)}/>

当用户在 map 上移动时,我如何才能停止过度的重新渲染,同时又不失去用户从卡片组件调整视口(viewport)的能力?

最佳答案

通过输入 viewportsetViewport在相同的上下文中,每次视口(viewport)更改时,您都会强制侧边栏重新渲染,因为它使用 useContext(ViewportContext) — 即使它只使用 setViewport上下文的一部分。有几个选项:

  • 通过简单地移动 useContext(ViewportContext) 来减少重新渲染对性能的影响放入子组件中,以便在视口(viewport)更新时仅呈现子组件,而不是整个侧边栏。
  • 如果您只需要单向更新(边栏按钮可以设置 map 的视口(viewport),但其他组件不需要知道用户何时在 map 上移动),那么您可以从 map 中删除 setViewport 调用。
  • 输入viewportsetViewport在不同的上下文中。这意味着两个 createContext()调用,但您仍然会保留一个 ViewportProvider 组件来呈现两个提供者,例如const [viewport, setViewport] = useState(); return <Context1.Provider value={viewport}><Context2.Provider value={setViewport}> ... .然后,你的侧边栏可以useContext仅针对它需要的上下文,并且不会在另一个更改时重新呈现。
  • 使用像 useContextSelector 这样的东西替换 const {setViewport} = useContext(ViewportContext)const setViewport = useContextSelector(ViewportContext, (ctx) => ctx.setViewport) .
  • 如果您正在考虑更广泛的架构更改,像 React Redux 这样的库或 Recoil可以提供避免此问题的替代设计。

(顺便说一句,在您编写的代码中,我建议您将传递给 valueViewportContext.Provider 包装在 useMemo(() => ({viewport, setViewport}), [viewport, setViewport]) 中,这样当 ViewportProvider 重新设置时它不会触发更新如果视口(viewport)没有改变则呈现。)

关于javascript - 使用 mapbox 和 react context 时防止过度重新渲染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70553742/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com