Tengo una aplicación donde necesito establecer la altura de un elemento (digamos "contenido de la aplicación") dinámicamente. Toma la altura del "cromo" de la aplicación y la resta y luego establece la altura del "contenido de la aplicación" para que se ajuste al 100% dentro de esas restricciones. Esto es súper simple con las vistas vanilla JS, jQuery o Backbone, pero estoy luchando por descubrir cuál sería el proceso correcto para hacer esto en React.
A continuación se muestra un componente de ejemplo. Quiero poder configurar app-content
la altura para que sea el 100% de la ventana menos el tamaño de ActionBar
y BalanceBar
, pero ¿cómo sé cuándo se representa todo y dónde colocaría el material de cálculo en esta clase de reacción?
/** @jsx React.DOM */
var List = require('../list');
var ActionBar = require('../action-bar');
var BalanceBar = require('../balance-bar');
var Sidebar = require('../sidebar');
var AppBase = React.createClass({
render: function () {
return (
<div className="wrapper">
<Sidebar />
<div className="inner-wrapper">
<ActionBar title="Title Here" />
<BalanceBar balance={balance} />
<div className="app-content">
<List items={items} />
</div>
</div>
</div>
);
}
});
module.exports = AppBase;
javascript
reactjs
Oscar Godson
fuente
fuente
Respuestas:
componentDidMount ()
Este método se llama una vez después de que se representa su componente. Entonces su código se vería así.
fuente
componentDidUpdate
si los valores pueden cambiar después del primer render.componentDidMount()
no causa una transición.componentDidMount: () => { setTimeout(addClassFunction())}
, o use rAF, la respuesta a continuación proporciona esta respuesta.Un inconveniente del uso
componentDidUpdate
, ocomponentDidMount
es que en realidad se ejecutan antes de que se dibujen los elementos dom, pero después de que se hayan pasado de React al DOM del navegador.Digamos, por ejemplo, si necesita establecer node.scrollHeight en el nodo renderizado.scrollTop, entonces los elementos DOM de React pueden no ser suficientes. Debe esperar hasta que los elementos estén pintados para obtener su altura.
Solución:
Utilícelo
requestAnimationFrame
para asegurarse de que su código se ejecute después de pintar su objeto recién renderizadofuente
_this.getDOMNode is not a function
¿Qué diablos es este código?En mi experiencia
window.requestAnimationFrame
, no fue suficiente para garantizar que el DOM se haya procesado / reflujo completo desdecomponentDidMount
. Tengo un código en ejecución que accede al DOM inmediatamente después de unacomponentDidMount
llamada y el uso exclusivowindow.requestAnimationFrame
daría como resultado que el elemento esté presente en el DOM; sin embargo, las actualizaciones de las dimensiones del elemento aún no se reflejan ya que aún no se ha producido un reflujo.La única forma verdaderamente fiable para que esto funcione era de envolver mi método en una
setTimeout
y unawindow.requestAnimationFrame
para asegurar Reaccionar de pila de llamadas actual se limpia antes de registrarse para el siguiente fotograma de render.Si tuviera que especular sobre por qué esto está ocurriendo / es necesario, podría ver Reaccionar actualizaciones de DOM por lotes y no aplicar los cambios al DOM hasta que se complete la pila actual.
En última instancia, si está utilizando mediciones DOM en el código que está disparando después de las devoluciones de llamada React, es probable que desee utilizar este método.
fuente
Solo para actualizar un poco esta pregunta con los nuevos métodos de gancho, simplemente puede usar el
useEffect
gancho:Además, si desea ejecutar antes de la pintura de diseño, use el
useLayoutEffect
gancho:fuente
Updates scheduled inside useLayoutEffect will be flushed synchronously, before the browser has a chance to paint.
que editaré.Puede cambiar el estado y luego hacer sus cálculos en la devolución de llamada setState . De acuerdo con la documentación de React, "se garantiza que se activará después de que se haya aplicado la actualización".
Esto debe hacerse en
componentDidMount
o en algún otro lugar del código (como en un controlador de eventos de cambio de tamaño) en lugar de hacerlo en el constructor.Esta es una buena alternativa
window.requestAnimationFrame
y no tiene los problemas que algunos usuarios han mencionado aquí (es necesario combinarlosetTimeout
o llamarlo varias veces). Por ejemplo:fuente
Siento que esta solución está sucia, pero aquí vamos:
Ahora me voy a sentar aquí y esperar los votos negativos.
fuente
React tiene pocos métodos de ciclo de vida que ayudan en estas situaciones, las listas incluyen, entre otras, getInitialState, getDefaultProps, componentWillMount, componentDidMount, etc.
En su caso y los casos que necesitan interactuar con los elementos DOM, debe esperar hasta que el dom esté listo, por lo tanto, use componentDidMount como se muestra a continuación:
También para obtener más información sobre el ciclo de vida en reaccionar, puede consultar el siguiente enlace: https://facebook.github.io/react/docs/state-and-lifecycle.html
fuente
Tuve el mismo problema.
En la mayoría de los escenarios usando el hack-ish
setTimeout(() => { }, 0)
encomponentDidMount()
trabajado.Pero no en un caso especial; y no quería usar el
ReachDOM findDOMNode
puesto que la documentación dice:(Fuente: findDOMNode )
Entonces, en ese componente en particular, tuve que usar el
componentDidUpdate()
evento, por lo que mi código terminó siendo así:Y entonces:
Finalmente, en mi caso, tuve que eliminar el oyente creado en
componentDidMount
:fuente
Después de renderizar, puede especificar la altura como se muestra a continuación y puede especificar la altura a los componentes de reacción correspondientes.
o puede especificar la altura de cada componente de reacción usando sass. Especifique los primeros 2 divisores principales del componente de reacción con ancho fijo y luego la altura del tercer componente principal con auto. Entonces, según el contenido del tercer div, se asignará la altura.
fuente
En realidad, estoy teniendo problemas con un comportamiento similar, renderizo un elemento de video en un Componente con su atributo de identificación, por lo que cuando RenderDOM.render () finaliza, carga un complemento que necesita la identificación para encontrar el marcador de posición y no lo encuentra.
El setTimeout con 0ms dentro del componentDidMount () lo arregló :)
fuente
De la documentación de ReactDOM.render () :
fuente
ReactDOM.render
, no para el de nivel de componenteReactElement.render
(que es el tema aquí).Para mí, ninguna combinación de
window.requestAnimationFrame
osetTimeout
produce resultados consistentes. A veces funcionó, pero no siempre, o a veces sería demasiado tarde.Lo arreglé haciendo un bucle
window.requestAnimationFrame
tantas veces como sea necesario.(Típicamente 0 o 2-3 veces)
La clave es
diff > 0
: aquí podemos asegurarnos exactamente cuando la página se actualice.fuente
Tuve una situación extraña cuando necesito imprimir un componente de reacción que recibe una gran cantidad de datos y pintar en el lienzo. He probado todos los enfoques mencionados, ninguno de ellos funcionó de manera confiable para mí, con requestAnimationFrame dentro de setTimeout obtengo un lienzo vacío en el 20% del tiempo, así que hice lo siguiente:
Básicamente hice una cadena de requestAnimationFrame's, no estoy seguro de si es una buena idea o no, pero hasta ahora funciona en el 100% de los casos (estoy usando 30 como valor para la variable n).
fuente
En realidad, hay una versión mucho más simple y limpia que usar el marco de animación de solicitud o los tiempos de espera. Iam se sorprendió de que nadie lo mencionara: el controlador de carga vanilla-js. Si puede, use el componente sí se montó, si no, simplemente vincule una función en el controlador de carga del componente jsx. Si desea que la función ejecute cada render, también ejecútela antes de devolverle los resultados en la función de render. el código se vería así:
}
fuente
Un poco de actualización con
ES6
clases en lugar deReact.createClass
Además, verifique los métodos del ciclo de vida del componente React: el ciclo de vida del componente
Cada componente tiene muchos métodos similares a,
componentDidMount
por ejemplo.componentWillUnmount()
- el componente está a punto de eliminarse del navegador DOMfuente