Tengo un mapa SVG en el que quiero mostrar información sobre herramientas cuando el usuario pasa el cursor sobre el elemento:
const Tooltip = ({ children }) => { return ( <div className="Tooltip"> <div className="Tooltip--content"> {children} </div> </div> ); } export default Tooltipy componente
const svgField = () => { const tooltip = useRef(null); // methods const FieldWrapper = styled('div')(({ theme }) => ({ width: '100%', height: '100%', position: 'relative', /* display */ overflow: 'hidden', '&':{ 'alignItems': "center", 'justifyContent': "center" }, [theme.breakpoints.up('xs')]: { display: 'none' }, [theme.breakpoints.up('lg')]: { display: 'flex' }, })); return ( <FieldWrapper > <div ref={tooltip} style={{position: 'absolute', display: 'none'}}> <Tooltip> {currentTooltipInfo} </Tooltip> </div> <svg className="Field--svg" width={fieldSize[0]} height={fieldSize[1]} sx={{ 'padding-top':'12px' }} > <g className="field"> { fields.map((d, i) => ( <path // onMouseMove={(e) => handleMouseMove(e, d)} /> )) } </g> </svg> </FieldWrapper > ) }ahora si uso ganchos, por ejemplo:
const [tooltipContent, setTooltipContent] = useState(null);e implementar handleMouseMove como:
const [tooltipContent, setTooltipContent] = useState(null); const handleMouseMove = (evt, country) => { tooltip.current.style.display = "block"; tooltip.current.style.left = evt.clientX + 10 + 'px'; tooltip.current.style.top = evt.clientY + 10 + 'px'; tooltip.current.style.border="1px solid black"; setTooltipContent("Some content"); } ¿No volvería a renderizar todo el componente, incluido SVG (que no es pequeño) y, por lo tanto, afectaría el rendimiento mientras solo necesito volver a renderizar el elemento de tooltip ?
¿Hay alguna manera de volver a representar solo el elemento de información sobre tooltip ? No soy competente en React , por lo que se agradece cada información.
Gracias.
Si desea evitar volver a renderizar el fragmento SVG, simplemente extrapólelo en un nuevo Componente y envuélvalo en React.memo , de esa manera no se volverá a renderizar si los accesorios que recibe no cambian.
Solo asegúrese de sacar ese Componente con estilo, FieldWrapper , de su Componente, ya que los Componentes con estilo no deben declararse dentro del cuerpo de un COmponent, o va a recrear uno nuevo en cada renderizado.
Una opción es memorizar el componente SVG.
const svg = useMemo(() => ( <svg className="Field--svg" width={fieldSize[0]} height={fieldSize[1]} sx={{ 'padding-top': '12px' }} > <g className="field"> { fields.map((d, i) => ( <path // onMouseMove={(e) => handleMouseMove(e, d)} /> )) } </g> </svg> ), [fieldSize, fields]); return ( <FieldWrapper > <div ref={tooltip} style={{ position: 'absolute', display: 'none' }}> <Tooltip> {currentTooltipInfo} </Tooltip> </div> {svg} </FieldWrapper > ); Esto dará como resultado que el SVG se vuelva a calcular/renderizar solo cuando cambie cualquiera de los valores en la matriz de dependencia ( fieldSize o fields ).