¿Cómo puedo obtener Reaccionar para volver a mostrar la vista cuando la ventana del navegador cambia de tamaño?
De fondo
Tengo algunos bloques que quiero a la presentación individual en la página, sin embargo también quiero actualizar cuando la ventana del navegador los cambios. Al final el resultado será algo como Ben Holanda Pinterest diseño, pero escrito utilizando Reaccionar no sólo de jQuery. Todavía estoy un camino.
Código
Aquí mi app:
var MyApp = React.createClass({
//does the http get from the server
loadBlocksFromServer: function() {
$.ajax({
url: this.props.url,
dataType: 'json',
mimeType: 'textPlain',
success: function(data) {
this.setState({data: data.events});
}.bind(this)
});
},
getInitialState: function() {
return {data: []};
},
componentWillMount: function() {
this.loadBlocksFromServer();
},
render: function() {
return (
<div>
<Blocks data={this.state.data}/>
</div>
);
}
});
React.renderComponent(
<MyApp url="url_here"/>,
document.getElementById('view')
)
Entonces tengo el Block
componente (equivalente a un Pin
en el anterior Pinterest ejemplo):
var Block = React.createClass({
render: function() {
return (
<div class="dp-block" style={{left: this.props.top, top: this.props.left}}>
<h2>{this.props.title}</h2>
<p>{this.props.children}</p>
</div>
);
}
});
y la lista/de la colección de Blocks
:
var Blocks = React.createClass({
render: function() {
//I've temporarily got code that assigns a random position
//See inside the function below...
var blockNodes = this.props.data.map(function (block) {
//temporary random position
var topOffset = Math.random() * $(window).width() + 'px';
var leftOffset = Math.random() * $(window).height() + 'px';
return <Block order={block.id} title={block.summary} left={leftOffset} top={topOffset}>{block.description}</Block>;
});
return (
<div>{blockNodes}</div>
);
}
});
Pregunta
Debo agregar jQuery cambio de tamaño de ventana? Si es así, ¿dónde?
$( window ).resize(function() {
//re-render the component
});
Hay una más «Reaccionar» manera de hacer esto?
El Uso De Reaccionar Ganchos:
Puede definir una costumbre Gancho que escucha a la ventana
resize
evento, algo como esto:La ventaja aquí es la lógica que está encapsulado, y usted puede utilizar este enlace en cualquier lugar que usted desea usar el tamaño de la ventana.
El uso de Reaccionar clases:
Se puede escuchar en componentDidMount, algo parecido a este componente que sólo muestra las dimensiones de la ventana (como
<span>Window size: 1024 x 768</span>
):this.updateDimensions
pasa aaddEventListener
es sólo una mera referencia de funciones que no tienen ningún valor parathis
cuando se le llama. Si una función anónima, o de una .llamada bind() se utiliza para agregarthis
, o he entendido mal?this
para todos los métodos definidos directamente en el componente.React.Component
en lugar deReact.createClass
, pero tuve que cambiar los detectores de eventos parawindow.addEventListener("resize", ::this.updateDimensions);
ywindow.removeEventListener("resize", ::this.updateDimensions);
en orden para que esto funcione.innerHeight
yinnerWidth
dewindow
. Y usted puede saltarcomponentWillMount
si utilizagetInitialState
para establecerheight
ywidth
.::
enlazar la sintaxis es de ahora sitepoint.com/bind-javascripts-this-keyword-react «el enlace del operador (::) no va a ser parte de ES7, como el ES7 características del set, fue congelado en febrero, el enlace operador es una propuesta para ES8»$
para jQueryuseLayoutEffect
para esteuseLayoutEffect
es apropiado para evitar el parpadeo.@SophieAlpert es correcto, +1, solo quiero ofrecer una versión modificada de su solución, sin jQuery, basado en esta respuesta.
Una solución muy simple:
componentWillUnmount()
!forceUpdate
se aplica de forma condicionalEs una forma simple y breve ejemplo del uso de es6 sin jQuery.
ganchos
::
enlazar operador devuelve un valor nuevo cada vez que se aplica. Para que su evento oyente no consigue realmente no registrados, ya que suremoveEventListener
termina pasando una función diferente de lo que fue originalmente aprobado paraaddEventListener
.Como de Reaccionar 16.8 puede utilizar Ganchos!
Edición de 2018: ahora Reaccionan de primera clase de apoyo para contexto
Voy a tratar de dar una respuesta genérica, que se dirige a este problema, pero un problema más general también.
Si usted no se preocupan por los efectos secundarios libs, usted puede simplemente utilizar algo como Packery
Si utiliza Fundente, podría crear una tienda que contienen la ventana de propiedades de forma que se mantenga un puro representar la función sin tener que consultar el objeto de la ventana cada vez.
En otros casos donde usted quiere construir un sitio web responsive, pero prefiere Reaccionar estilos en línea para consultas de medios de comunicación, o si desea que el HTML/JS comportamiento a cambios de acuerdo al ancho de la ventana, sigue leyendo:
¿Qué es Reaccionar contexto y por qué hablo de ella
Reaccionar contexto una no está en la API pública y permite pasar de las propiedades de toda una jerarquía de componentes.
Reaccionar contexto es particularmente útil para pasar a la totalidad de su aplicación las cosas que nunca cambia (es utilizado por muchos de Flujo de marcos a través de un mixin). Se puede utilizar para la aplicación de la tienda de negocios invariantes (como el conectado id de usuario, por lo que está disponible en todas partes).
Pero también puede ser utilizado para almacenar cosas que pueden cambiar. El problema es que cuando los cambios de contexto, todos los componentes que uso debe ser re-renderizados y no es fácil hacerlo, la mejor solución es a menudo para desmontar/montar el conjunto de la aplicación con el nuevo contexto. Recuerde forceUpdate no es recursiva.
Así como entender el contexto es práctico, pero no hay un impacto en el rendimiento cuando se cambia, por lo que se debe más bien a que no cambian a menudo.
Qué poner en contexto
Aquí hay cosas que no cambian con frecuencia:
El actual idioma del usuario:
No cambia muy oftenly, y cuando lo hace, como toda la aplicación está traducida tenemos que volver a hacer todo: un muy buen caso de uso de caliente langage cambio
La ventana de propiedades de
La anchura y la altura para que no cambian con frecuencia, pero cuando hacemos nuestro diseño y el comportamiento pueden tener que adaptarse. Para el diseño, a veces, es fácil de personalizar con CSS técnicaconsultas, pero a veces no lo es y requiere de una diferente estructura HTML. Para el comportamiento que usted tiene que manejar esto con Javascript.
No quieres volver a hacer todo en cada evento de cambio de tamaño, por lo que debes de rebote de los eventos de cambio de tamaño.
Lo que entiendo de tu problema es que quieres saber cuántos elementos de la pantalla de acuerdo al ancho de la pantalla. Así que en primer lugar tiene que definir sensible puntos de interrupción, y enumerar el número de diferentes tipos de disposición de que se puede tener.
Por ejemplo:
Sobre eventos de cambio de tamaño (rebotada), usted puede conseguir fácilmente el actual tipo de diseño, mediante la consulta de la ventana de objetos.
A continuación, puede comparar el tipo de diseño con el antiguo tipo de diseño, y si ha cambiado, vuelva a procesar la aplicación con un nuevo contexto: esto permite evitar la re-representación de la aplicación cuando el usuario ha de desencadenar eventos de cambio de tamaño, pero en realidad el tipo de diseño no ha cambiado, por lo que sólo se reproducen cuando sea necesario.
Una vez que tienes eso, puedes simplemente utilizar el tipo de diseño dentro de la aplicación (accesible a través del contexto), de modo que usted puede personalizar el HTML, el comportamiento, las clases CSS… Usted sabe que su tipo de diseño en el interior del Reaccionan de procesamiento función, así que esto significa que usted puede escribir con seguridad de sitios web sensibles mediante el uso de estilos en línea, y no es necesario técnicaconsultas a todos.
Si utiliza Fundente, puede utilizar una tienda en lugar de Reaccionar de contexto, pero si tu aplicación tiene un montón de respuesta de los componentes tal vez es más fácil usar el contexto?
Puedo usar @senornestor ‘s solución, pero para ser totalmente correcta, retire el detector de eventos así:
De lo contrario, usted ‘ll obtener la advertencia:
Me iba a saltar todas las respuestas anteriores y comenzar a utilizar el
react-dimensions
Mayor Componente de Orden.https://github.com/digidem/react-dimensions
Acaba de agregar un simple
import
y una llamada a una función, y se puede acceder athis.props.containerWidth
ythis.props.containerHeight
en el componente.react-dimensions
incluso funciona para cambiar mediante programación dimensiones (por ejemplo, el tamaño de un div cambiado, lo que afecta el tamaño de su contenedor, por lo que necesita para actualizar su tamaño). Ben Alpert la respuesta sólo ayuda en la ventana del navegador de eventos de cambio de tamaño. Ver aquí: github.com/digidem/react-dimensions/issues/4max-height: XXvh
, pero creo que no siempre es suficiente.react-dimensions
controla los cambios en el tamaño de la ventana, el diseño flexbox cambios y cambios debido a JavaScript cambio de tamaño. Creo que la cubre. ¿Tiene usted un ejemplo que no maneje correctamente?window.innerWidth
,window.innerHeight
.react-dimensions
resuelve la parte más importante del problema, y también desencadena su disposición el código cuando la ventana cambia de tamaño (así como cuando el tamaño del recipiente cambios).Este código es el uso de la nueva Reaccionar contexto de la API:
Entonces usted puede utilizar siempre que lo desee en su código como este:
No necesariamente se debe a la fuerza de un re-procesamiento.
Esto podría no ayudar a OP, pero en mi caso sólo tuve que actualizar el
width
yheight
atributos en mi lienzo (que no se puede hacer con CSS).Se parece a esto:
No estoy seguro si este es el mejor método, pero lo que funcionó para mí fue la primera creación de una Tienda, me llamó WindowStore:
Entonces yo que la guarde en mis componentes, algo como esto:
FYI, estos archivos fueron parcialmente tapizados.
onresize
podrían enviar unWindowResizedAction
.Sé que esto ha sido contestado, pero sólo pensé en compartir mi solución como la respuesta, a pesar de que gran, ahora puede ser un poco anticuado.
La única diferencia real es que estoy eliminación de rebotes (sólo se ejecuta cada 200ms) la updateWindowDimensions en el evento de cambio de tamaño para aumentar el rendimiento un poco, PERO no eliminación de rebotes cuando se llama en ComponentDidMount.
Estaba encontrando el rebote hecho bastante lag al monte, a veces, si usted tiene una situación en la que es montaje a menudo.
A un menor de edad optimización, pero espero que ayude a alguien!
initUpdateWindowDimensions
método?Sólo necesita definir el evento resize de la función.
A continuación, actualizar los renderizadores tamaño ( lienzo ), asignar una nueva relación de aspecto de la cámara.
Desmontar y remouting es un loco de la solución, en mi opinión….
a continuación es el montaje si es necesario.
Sólo para mejorar en @senornestor la solución para usar
forceUpdate
y @gkri la solución para la eliminación de laresize
detector de eventos en el componente de desmontar:bind(this)
en el constructorOtro método es usar un «dummy» del estado en lugar de
forceUpdate
:Tuvieron que obligar a ‘esta’ en el constructor para que funcione con la Clase de sintaxis
Gracias a todos por las respuestas. Aquí está mi Reaccionan + Recomponer. Se trata de una Alta Función de Orden que incluye el
windowHeight
ywindowWidth
propiedades para el componente.https://github.com/renatorib/react-sizes es una HOC para ello, mientras que todavía mantiene un buen rendimiento.
Quería compartir este genial cosa que me acabo de encontrar usando
window.matchMedia
.matches
devolverá true o false si la ventana es mayor o menor que la especificada ancho máximo valor, esto significa que no hay necesidad de limitar el oyente, como el matchMedia sólo se desencadena una vez, cuando el booleano cambios.Mi código puede ser fácilmente ajustado para incluir
useState
para guardar el booleano matchMedia devuelve, y lo utilizan para representar condicionalmente un componente, el fuego de la acción, etc.Por esta razón mejor es usar este tipo de datos de CSS o JSON datos de archivo y, a continuación, con los datos de configuración del nuevo estado con este.estado({width: «algo de valor»,altura:»algo de valor» }); o escribir código que utilice los datos de la anchura de los datos de la pantalla en auto de trabajo si desea sensible mostrar imágenes