Tengo una aplicación que usa un mapa de mapbox y estoy tratando de permitir un ajuste de la ventana gráfica desde otro componente de tarjeta separado. La forma en que hice esto fue creando un contexto de ventana gráfica y pasando la ventana gráfica y la función que la establece tanto al mapa como al componente de la tarjeta.
Esto funciona, pero tengo un problema con la reproducción. Cada vez que el usuario se desplaza por el mapa, la ventana gráfica cambia constantemente y, por lo tanto, todo lo que se encuentra dentro del Proveedor de ventana gráfica se vuelve a representar constantemente. A continuación se muestra una versión simplificada del código.
aplicación
<ViewportProvider> *Container that holds both the map and the sidebar that renders the card components* </ViewportProvider>ViewportProvider
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} /> ); }Mapa
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}/>Tarjeta
const {setViewport} = useContext(ViewportContext) <Card onClick={setViewport(...newValue)}/>¿Cómo puedo detener la reproducción excesiva cuando el usuario se mueve por el mapa sin perder la capacidad de que el usuario ajuste la ventana gráfica desde el componente de la tarjeta?
Al poner viewport y setViewport en el mismo contexto, está obligando a la barra lateral a volver a renderizarse cada vez que cambia el viewport, porque usa useContext(ViewportContext) , aunque solo usa la parte setViewport del contexto. Hay algunas opciones:
useContext(ViewportContext) a un subcomponente, de modo que solo el subcomponente, no toda la barra lateral, se renderice cada vez que se actualice la ventana gráfica.viewport y setViewport en contextos separados. Esto significaría dos llamadas createContext() , pero aún mantendría un solo componente ViewportProvider que representa ambos proveedores, por ejemplo, const [viewport, setViewport] = useState(); return <Context1.Provider value={viewport}><Context2.Provider value={setViewport}> ... . Luego, su barra lateral puede useContext solo para el contexto que necesita, y no se volverá a representar cuando el otro cambie.useContextSelector para reemplazar const {setViewport} = useContext(ViewportContext) con const setViewport = useContextSelector(ViewportContext, (ctx) => ctx.setViewport) . (Por cierto, en su código tal como está escrito, le recomendaría envolver el value que pasa a ViewportContext.Provider en un useMemo(() => ({viewport, setViewport}), [viewport, setViewport]) , para que no desencadena una actualización cuando ViewportProvider se vuelve a representar si la ventana gráfica no ha cambiado).