He creado un D3 svg básico solo para probar algunas cosas con reaccionar. Como referencia, aquí está mi código:
Aplicación.js
import './App.css'; import Graph from './Graph/Graph'; function App() { return ( <Graph /> ); } export default App;Gráfico.js
import * as d3 from "d3" function Graph(props) { let svg = d3.select("svg") svg.append('rect') .attr("height", 10) .attr("width", 10) .style("fill", "Green"); return ( <div> <svg id="svgID" width="640" height="480"></svg> <script src="https://d3js.org/d3.v5.min.js"></script> <script src="index.js"></script> </div> ) } export default GraphEl problema que tengo es dónde carga el rectángulo verde solo a veces, parece que no tengo control sobre cuándo se carga y cuándo no.
Creo que podría deberse a que el SVG se devuelve antes de que tenga tiempo de agregarle algo, sin embargo, no estoy seguro de una solución. ¿Alguna ayuda?
Debe tomar una referencia de su elemento DOM svg que persiste entre los renderizados. La API React le brinda el useRef para hacer eso con un componente funcional (ver documentos) .
Para vincular un elemento DOM con una referencia, debe usar el atributo ref JSX.
<svg ref={svgRef} id="svgID" width="640" height="480"></svg> Dado que useRef no indica cuándo está vinculado con el elemento DOM, debe acoplar la "ref" devuelta con useEffect hook para verificar cuándo la corriente está vinculada con el elemento DOM svg .
import React, { useRef, useEffect } from 'react' import * as d3 from "d3" function Graph(props) { const svgRef = useRef(null); useEffect( () => { // Check that svg element has been rendered if(svg.current) { let svg = d3.select(svgRef.current) svg.append('rect') .attr("height", 10) .attr("width", 10) .style("fill", "Green"); } } },[svgRef.current]) return ( <div> <svg ref={svgRef} id="svgID" width="640" height="480"></svg> </div> ) } export default Graph