Tengo este problema conceptual y tengo un codesandbox realmente simple y mínimo para ello:
Quiero llevar un recuento de los componentes que se representan en mi página (por componente). Estos son mis componentes. (Estoy trabajando con Preact pero realmente estamos hablando de funciones aquí)
function Element() { return " " //I'm not important } function Container() { //container is repeating my Element return <div> <Element /> <Element /> <Element /> <Element /> </div> }Mantengo el recuento de elementos y contenedores en la página con una función de orden superior que realiza un seguimiento del recuento agregando una propiedad al componente solo si es el primero (firstType = true).
Quiero hacer esto porque este tipo de componente necesita renderizarse de manera diferente la primera vez. (<definiciones> para svg)
Puedo hacer eso fácilmente con esta función de orden superior
function Counter(Component) { let count = 0; return function (...props) { //this is for the purpose of the debugging return <>{++count} <Component {...props[0]} /> </> } }El problema ocurrió cuando en otro HOC intenté renderizar el componente con renderToStaticString (),
PD: necesito eso en mi Componente para poder saber su ancho y alto (también podría hacer esto con una referencia al nodo dom y una llamada getBBox pero quiero que mi aplicación funcione sin un navegador).
Mi mejor opción sería convertir el componente en una cadena, obtener los puntos de la ruta y luego medir la ruta con getBBox del lado del servidor de PathCommander o tal vez con otras técnicas de ssr como PhantomJS.
Todo esto funcionaría muy bien, pero nuevamente cuando ejecuto renderToStaticString en mi componente, el componente en sí también es llamado por renderToStaticString y, por lo tanto, Counting HOC se involucra arruinando el conteo de los componentes que tenía).
Esto se debe a que esta vez , cuando llamo a la función de mi componente, la llamo solo para medir la ruta sobre la marcha, no para representar el componente en la página como lo habría hecho con un React.render() normal. o en una situación de renderizado ssr normal. Entonces necesito restablecer el conteo a 0 después de hacer este render sobre la marcha. Entonces, en la página, seguirá actuando correctamente, pero probé todo sin suerte.
En serio, no puedo pensar en una solución simple y correcta que resuelva este rompecabezas por completo, si alguien tiene algunas ideas iniciales o información útil, ¡COMPARTA! Aquí también hice un codesandbox con el que puedes jugar (simplemente quita el comentario de //renderToStaticString para que deje de funcionar (tienes que recargar manualmente o guardar automáticamente no restablecerá el conteo a 0 (esto es porque no es ssr aquí ofc).
Una técnica podría ser crear una referencia React.createElement y anularla con una función contenedora que incremente un elementCount .
function App() { return <div> <p>Hello world</p> <p>Another paragraph and <span>here</span></p> <p>This is the sixth element, counting the outermost App</p> </div> } let elementCount = 0 const createElement = React.createElement React.createElement = (...args) => { elementCount++ return createElement(...args) } ReactDOM.render(<App/>, document.querySelector("#app")) console.log("total elements", elementCount) <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.14.0/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.14.0/umd/react-dom.production.min.js"></script> <div id="app"></div> total elements 6Esto cuenta seis (6) elementos.
<App><div><p>Hello world<p>Another paragraph and<span><p>This is the sixth... No estoy seguro de si funcionará con renderToStaticString o no. Pruébelo y háganoslo saber.