¿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?

InformationsquelleAutor digibake | 2013-09-25

19 Comentarios

  1. 435

    El Uso De Reaccionar Ganchos:

    Puede definir una costumbre Gancho que escucha a la ventana resize evento, algo como esto:

    import React, { useLayoutEffect, useState } from 'react';
    
    function useWindowSize() {
      const [size, setSize] = useState([0, 0]);
      useLayoutEffect(() => {
        function updateSize() {
          setSize([window.innerWidth, window.innerHeight]);
        }
        window.addEventListener('resize', updateSize);
        updateSize();
        return () => window.removeEventListener('resize', updateSize);
      }, []);
      return size;
    }
    
    function ShowWindowDimensions(props) {
      const [width, height] = useWindowSize();
      return <span>Window size: {width} x {height}</span>;
    }

    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>):

    import React from 'react';
    
    class ShowWindowDimensions extends React.Component {
      state = { width: 0, height: 0 };
      render() {
        return <span>Window size: {this.state.width} x {this.state.height}</span>;
      }
      updateDimensions = () => {
        this.setState({ width: window.innerWidth, height: window.innerHeight });
      };
      componentDidMount() {
        window.addEventListener('resize', this.updateDimensions);
      }
      componentWillUnmount() {
        window.removeEventListener('resize', this.updateDimensions);
      }
    }
    • ¿Cómo funciona esto? El this.updateDimensions pasa a addEventListener es sólo una mera referencia de funciones que no tienen ningún valor para this cuando se le llama. Si una función anónima, o de una .llamada bind() se utiliza para agregar this, o he entendido mal?
    • Estoy un poco tarde aquí, pero Reaccionan de auto-une this para todos los métodos definidos directamente en el componente.
    • consulte facebook.github.io/react/tips/dom-event-listeners.html 🙂
    • tal vez esto ha cambiado con ES6 y React.Component en lugar de React.createClass, pero tuve que cambiar los detectores de eventos para window.addEventListener("resize", ::this.updateDimensions);y window.removeEventListener("resize", ::this.updateDimensions); en orden para que esto funcione.
    • sí, ES6 clases son sólo las clases normales, así que no hay auto-unión con ellos.
    • No jQuery necesario usar innerHeight y innerWidth de window. Y usted puede saltar componentWillMount si utiliza getInitialState para establecer height y width.
    • se parece a la :: 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»
    • Podemos zanja de la $ para jQuery
    • Se puede/debe hacer esto para cada uno de los componentes que necesita esta lógica?
    • Yo creo que usted no necesita useLayoutEffect para este
    • Ya que en la mayoría de los casos esto podría ser usado para alterar la apariencia visual de un componente, useLayoutEffect es apropiado para evitar el parpadeo.
    • el gancho no es muy utilizado para modificar directamente la apariencia, sin embargo, el gancho se utiliza simplemente para añadir un detector de eventos
    • Se llama updateSize del efecto. Tienes razón que el detector de eventos podría ser trasladado a un useEffect.

  2. 128

    @SophieAlpert es correcto, +1, solo quiero ofrecer una versión modificada de su solución, sin jQuery, basado en esta respuesta.

    var WindowDimensions = React.createClass({
        render: function() {
            return <span>{this.state.width} x {this.state.height}</span>;
        },
        updateDimensions: function() {
    
        var w = window,
            d = document,
            documentElement = d.documentElement,
            body = d.getElementsByTagName('body')[0],
            width = w.innerWidth || documentElement.clientWidth || body.clientWidth,
            height = w.innerHeight|| documentElement.clientHeight|| body.clientHeight;
    
            this.setState({width: width, height: height});
            //if you are using ES2015 I'm pretty sure you can do this: this.setState({width, height});
        },
        componentWillMount: function() {
            this.updateDimensions();
        },
        componentDidMount: function() {
            window.addEventListener("resize", this.updateDimensions);
        },
        componentWillUnmount: function() {
            window.removeEventListener("resize", this.updateDimensions);
        }
    });
    • sólo funciona cuando usted tiene su IE relacionados con polyfills establecido para la vainilla JS detectores de eventos
    • usted puede elaborar? Admito que yo sólo he probado esto en Chrome. Estás diciendo la ventana.addEventListener no va a funcionar en IE sin polyfills?
    • href=»http://caniuse.com/#search=addeventlistener» >caniuse.com/#search=addeventlistener indica ie8 gustaría tener un problema
    • Lo que yo veo. Sí.. Así que mi solución no funciona en IE 8, pero funciona desde las 9 en :). Gracias.
    • ¿Alguien realmente todavía se preocupan por IE8? O es la costumbre?
    • el año pasado, cuando hice ese comentario, nos hizo compatible con IE8 en la parte pública de nuestro producto (y Reaccionar en una sección diferente). contento de informar que estamos pasando de pronto. pero whatcha que va a hacer cuando su código de toques 14-15 millones de dominios de nivel internacional?

  3. 48

    Una solución muy simple:

    resize = () => this.forceUpdate()
    
    componentDidMount() {
      window.addEventListener('resize', this.resize)
    }
    
    componentWillUnmount() {
      window.removeEventListener('resize', this.resize)
    }
    • No te olvides de estrangular a la actualización de fuerza o se va a ver muy lento.
    • También no se olvide de quitar el oyente en componentWillUnmount()!
    • Esta es la mejor de las soluciones si es estrangulado. Me refiero a que si el forceUpdate se aplica de forma condicional
    • por favor, ¿de qué estás hablando, es el forceUpdate estrangulado aquí? Parece que sí, ya que está feliz sólo en caso de cambio de tamaño
    • No es el forceUpdate (la cosa se llama) que tiene que ser regulada, es el evento de cambio de tamaño de cocción que necesita ser regulada (la cosa de la cocción). Eventos de tamaño técnicamente puede ser llamado en cada píxel, ya que el tamaño de una ventana de grandes a pequeñas. Cuando un usuario hace esto de manera rápida, que es más eventos de los que te importan. Peor, estás de unión el subproceso de interfaz de usuario para el Javascript hilo en el sentido de su aplicación va a empezar a tener un serio lento sintiendo como se trata de manejar que cada caso de forma individual.
    • En lugar de ejecutar la función de cambiar el tamaño a cada píxel, que se ejecuta en algún periódica breve cantidad de tiempo para dar la ilusión de fluidez que usted maneje siempre el primer y el último evento, dando la sensación de que es una manera fluida manejo el cambio de tamaño.

  4. 34

    Es una forma simple y breve ejemplo del uso de es6 sin jQuery.

    import React, { Component } from 'react';
    
    export default class CreateContact extends Component {
      state = {
        windowHeight: undefined,
        windowWidth: undefined
      }
    
      handleResize = () => this.setState({
        windowHeight: window.innerHeight,
        windowWidth: window.innerWidth
      });
    
      componentDidMount() {
        this.handleResize();
        window.addEventListener('resize', this.handleResize)
      }
    
      componentWillUnmount() {
        window.removeEventListener('resize', this.handleResize)
      }
    
      render() {
        return (
          <span>
            {this.state.windowWidth} x {this.state.windowHeight}
          </span>
        );
      }
    }

    ganchos

    import React, { useEffect, useState } from "react";
    
    let App = () => {
      const [windowWidth, setWindowWidth] = useState(0);
      const [windowHeight, setWindowHeight] = useState(0);
      let resizeWindow = () => {
        setWindowWidth(window.innerWidth);
        setWindowHeight(window.innerHeight);
      };
    
      useEffect(() => {
        resizeWindow();
        window.addEventListener("resize", resizeWindow);
        return () => window.removeEventListener("resize", resizeWindow);
      }, []);
    
      return (
        <div>
          <span>
            {windowWidth} x {windowHeight}
          </span>
        </div>
      );
    };
    • Este es un bonito, sucinta respuesta pero AFAICT tiene un error: a menos que me equivoco, el :: enlazar operador devuelve un valor nuevo cada vez que se aplica. Para que su evento oyente no consigue realmente no registrados, ya que su removeEventListener termina pasando una función diferente de lo que fue originalmente aprobado para addEventListener.
  5. 17

    Como de Reaccionar 16.8 puede utilizar Ganchos!

    /* globals window */
    import React, { useState, useEffect } from 'react'
    import _debounce from 'lodash.debounce'
    
    const Example = () => {
      const [width, setWidth] = useState(window.innerWidth)
    
      useEffect(() => {
        const handleResize = _debounce(() => setWidth(window.innerWidth), 100)
    
        window.addEventListener('resize', handleResize);
    
        return () => {
          window.removeEventListener('resize', handleResize);
        }
      }, [])
    
      return <>Width: {width}</>
    }
  6. 13

    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

    • Invariantes: como conectado userId, sessionToken, lo que sea…
    • Cosas que no cambian con frecuencia

    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:

    • Diseño «1col», para ancho de <= 600
    • Diseño «2col», para 600 < width < 1000
    • Diseño «3col», para 1000 <= ancho

    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?

  7. 10

    Puedo usar @senornestor ‘s solución, pero para ser totalmente correcta, retire el detector de eventos así:

    componentDidMount() {
        window.addEventListener('resize', this.handleResize);
    }
    
    componentWillUnmount(){
        window.removeEventListener('resize', this.handleResize);
    }
    
    handleResize = () => {
        this.forceUpdate();
    };

    De lo contrario, usted ‘ll obtener la advertencia:

    Advertencia: forceUpdate(…): sólo Puede actualizar montada o montaje
    componente. Esto generalmente significa que usted llama forceUpdate() en una desmontado
    componente. Este es un no-op. Por favor, compruebe el código de la XXX
    componente.

    • Usted está recibiendo la advertencia por una razón: lo que estás haciendo es una mala práctica. Su función render() debe ser una función pura de accesorios y el estado. En su caso, usted debe guardar el nuevo tamaño en el estado.
  8. 7

    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 a this.props.containerWidth y this.props.containerHeight en el componente.

    //Example using ES6 syntax
    import React from 'react'
    import Dimensions from 'react-dimensions'
    
    class MyComponent extends React.Component {
      render() (
        <div
          containerWidth={this.props.containerWidth}
          containerHeight={this.props.containerHeight}
        >
        </div>
      )
    }
    
    export default Dimensions()(MyComponent) //Enhanced component
    • Esto no le da el tamaño de la ventana, sólo el contenedor.
    • Sí, ese es el punto. El tamaño de la ventana es trivial encontrar. El tamaño de un contenedor es mucho más difícil de encontrar y mucho más útil para Reaccionar componente. La última versión de 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/4
    • Sí reaccionar-dimensiones es una gran biblioteca. No siempre es suficiente, aunque he diseños que dependen tanto del tamaño del contenedor y el tamaño de la ventana, así como a escala ciertas cosas de tal modo que se ajuste. Es posible que yo pueda reestructurar algunos de estos para uso max-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?
    • En uso de uno de mis casos de uso donde no sería suficiente, tenemos un algoritmo de diseño que lugares se adapta escalable bloques de contenidos de la página en filas. Dentro de ciertos límites, queremos que las filas para que se ajuste alrededor de 2,5 filas a la altura de la pantalla. La anchura es suficiente para hacer del tamaño del recipiente, pero la altura que necesita saber el tamaño de la ventana.
    • El tamaño de la ventana es trivial obtener. No hay necesidad de una biblioteca para que: 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 proyecto ya no se mantiene activa.

  9. 7

    Este código es el uso de la nueva Reaccionar contexto de la API:

      import React, { PureComponent, createContext } from 'react';
    
      const { Provider, Consumer } = createContext({ width: 0, height: 0 });
    
      class WindowProvider extends PureComponent {
        state = this.getDimensions();
    
        componentDidMount() {
          window.addEventListener('resize', this.updateDimensions);
        }
    
        componentWillUnmount() {
          window.removeEventListener('resize', this.updateDimensions);
        }
    
        getDimensions() {
          const w = window;
          const d = document;
          const documentElement = d.documentElement;
          const body = d.getElementsByTagName('body')[0];
          const width = w.innerWidth || documentElement.clientWidth || body.clientWidth;
          const height = w.innerHeight || documentElement.clientHeight || body.clientHeight;
    
          return { width, height };
        }
    
        updateDimensions = () => {
          this.setState(this.getDimensions());
        };
    
        render() {
          return <Provider value={this.state}>{this.props.children}</Provider>;
        }
      }

    Entonces usted puede utilizar siempre que lo desee en su código como este:

    <WindowConsumer>
      {({ width, height }) =>  //do what you want}
    </WindowConsumer>
  10. 6

    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 y height atributos en mi lienzo (que no se puede hacer con CSS).

    Se parece a esto:

    import React from 'react';
    import styled from 'styled-components';
    import {throttle} from 'lodash';
    
    class Canvas extends React.Component {
    
        componentDidMount() {
            window.addEventListener('resize', this.resize);
            this.resize();
        }
    
        componentWillUnmount() {
            window.removeEventListener('resize', this.resize);
        }
    
        resize = throttle(() => {
            this.canvas.width = this.canvas.parentNode.clientWidth;
            this.canvas.height = this.canvas.parentNode.clientHeight;
        },50)
    
        setRef = node => {
            this.canvas = node;
        }
    
        render() {
            return <canvas className={this.props.className} ref={this.setRef} />;
        }
    }
    
    export default styled(Canvas)`
       cursor: crosshair;
    `
  11. 5

    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:

    import {assign, events} from '../../libs';
    import Dispatcher from '../dispatcher';
    import Constants from '../constants';
    let CHANGE_EVENT = 'change';
    let defaults = () => {
    return {
    name: 'window',
    width: undefined,
    height: undefined,
    bps: {
    1: 400,
    2: 600,
    3: 800,
    4: 1000,
    5: 1200,
    6: 1400
    }
    };
    };
    let save = function(object, key, value) {
    //Save within storage
    if(object) {
    object[key] = value;
    }
    //Persist to local storage
    sessionStorage[storage.name] = JSON.stringify(storage);
    };
    let storage;
    let Store = assign({}, events.EventEmitter.prototype, {
    addChangeListener: function(callback) {
    this.on(CHANGE_EVENT, callback);
    window.addEventListener('resize', () => {
    this.updateDimensions();
    this.emitChange();
    });
    },
    emitChange: function() {
    this.emit(CHANGE_EVENT);
    },
    get: function(keys) {
    let value = storage;
    for(let key in keys) {
    value = value[keys[key]];
    }
    return value;
    },
    initialize: function() {
    //Set defaults
    storage = defaults();
    save();
    this.updateDimensions();
    },
    removeChangeListener: function(callback) {
    this.removeListener(CHANGE_EVENT, callback);
    window.removeEventListener('resize', () => {
    this.updateDimensions();
    this.emitChange();
    });
    },
    updateDimensions: function() {
    storage.width =
    window.innerWidth ||
    document.documentElement.clientWidth ||
    document.body.clientWidth;
    storage.height =
    window.innerHeight ||
    document.documentElement.clientHeight ||
    document.body.clientHeight;
    save();
    }
    });
    export default Store;

    Entonces yo que la guarde en mis componentes, algo como esto:

    import WindowStore from '../stores/window';
    let getState = () => {
    return {
    windowWidth: WindowStore.get(['width']),
    windowBps: WindowStore.get(['bps'])
    };
    };
    export default React.createClass(assign({}, base, {
    getInitialState: function() {
    WindowStore.initialize();
    return getState();
    },
    componentDidMount: function() {
    WindowStore.addChangeListener(this._onChange);
    },
    componentWillUnmount: function() {
    WindowStore.removeChangeListener(this._onChange);
    },
    render: function() {
    if(this.state.windowWidth < this.state.windowBps[2] - 1) {
    //do something
    }
    //return
    return something;
    },
    _onChange: function() {
    this.setState(getState());
    }
    }));

    FYI, estos archivos fueron parcialmente tapizados.

    • Almacenar el estado sólo debe cambiar en respuesta a un enviado de acción. Esto definitivamente no es una buena manera de hacer esto.
    • de hecho, tal vez mejor reubicados en el componente como en las otras respuestas.
    • O mejor aún, onresize podrían enviar un WindowResizedAction.
    • Esto es un exceso.
  12. 4

    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.

        constructor (props) {
    super(props)
    this.state = { width: '0', height: '0' }
    this.initUpdateWindowDimensions = this.updateWindowDimensions.bind(this)
    this.updateWindowDimensions = debounce(this.updateWindowDimensions.bind(this), 200)
    }
    componentDidMount () {
    this.initUpdateWindowDimensions()
    window.addEventListener('resize', this.updateWindowDimensions)
    }
    componentWillUnmount () {
    window.removeEventListener('resize', this.updateWindowDimensions)
    }
    updateWindowDimensions () {
    this.setState({ width: window.innerWidth, height: window.innerHeight })
    }

    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!

    • Donde es la definición de los initUpdateWindowDimensions método?
    • Es definido en el constructor 🙂 es simplemente updateWindowDimensions vinculado al componente pero sin el rebote.
  13. 2
    componentDidMount() {
    //Handle resize
    window.addEventListener('resize', this.handleResize);
    }
    handleResize = () => {
    this.renderer.setSize(this.mount.clientWidth, this.mount.clientHeight);
    this.camera.aspect = this.mount.clientWidth / this.mount.clientHeight;
    this.camera.updateProjectionMatrix();
    };

    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.

                <div
    className={this.state.canvasActive ? 'canvasContainer isActive' : 'canvasContainer'}
    ref={mount => {
    this.mount = mount;
    }}
    />
  14. 2

    Sólo para mejorar en @senornestor la solución para usar forceUpdate y @gkri la solución para la eliminación de la resize detector de eventos en el componente de desmontar:

    1. no te olvides de acelerador (o de rebote) la llamada para cambiar el tamaño de
    2. asegúrese de bind(this) en el constructor
    import React from 'react'
    import { throttle } from 'lodash'
    class Foo extends React.Component {
    constructor(props) {
    super(props)
    this.resize = throttle(this.resize.bind(this), 100)
    }
    resize = () => this.forceUpdate()
    componentDidMount() {
    window.addEventListener('resize', this.resize)
    }
    componentWillUnmount() {
    window.removeEventListener('resize', this.resize)
    }
    render() {
    return (
    <div>{window.innerWidth} x {window.innerHeight}</div>
    )
    }
    }

    Otro método es usar un «dummy» del estado en lugar de forceUpdate:

    import React from 'react'
    import { throttle } from 'lodash'
    class Foo extends React.Component {
    constructor(props) {
    super(props)
    this.state = { foo: 1 }
    this.resize = throttle(this.resize.bind(this), 100)
    }
    resize = () => this.setState({ foo: 1 })
    componentDidMount() {
    window.addEventListener('resize', this.resize)
    }
    componentWillUnmount() {
    window.removeEventListener('resize', this.resize)
    }
    render() {
    return (
    <div>{window.innerWidth} x {window.innerHeight}</div>
    )
    }
    }
  15. 1

    Tuvieron que obligar a ‘esta’ en el constructor para que funcione con la Clase de sintaxis

    class MyComponent extends React.Component {
    constructor(props) {
    super(props)
    this.resize = this.resize.bind(this)      
    }
    componentDidMount() {
    window.addEventListener('resize', this.resize)
    }
    componentWillUnmount() {
    window.removeEventListener('resize', this.resize)
    }
    }
  16. 1

    Gracias a todos por las respuestas. Aquí está mi Reaccionan + Recomponer. Se trata de una Alta Función de Orden que incluye el windowHeight y windowWidth propiedades para el componente.

    const withDimensions = compose(
    withStateHandlers(
    ({
    windowHeight,
    windowWidth
    }) => ({
    windowHeight: window.innerHeight,
    windowWidth: window.innerWidth
    }), {
    handleResize: () => () => ({
    windowHeight: window.innerHeight,
    windowWidth: window.innerWidth
    })
    }),
    lifecycle({
    componentDidMount() {
    window.addEventListener('resize', this.props.handleResize);
    },
    componentWillUnmount() {
    window.removeEventListener('resize');
    }})
    )
  17. 1

    https://github.com/renatorib/react-sizes es una HOC para ello, mientras que todavía mantiene un buen rendimiento.

    import React from 'react'
    import withSizes from 'react-sizes'
    @withSizes(({ width }) => ({ isMobile: width < 480 }))
    class MyComponent extends Component {
    render() {
    return <div>{this.props.isMobile ? 'Is Mobile' : 'Is Not Mobile'}</div>
    }
    }
    export default MyComponent
  18. 1

    Quería compartir este genial cosa que me acabo de encontrar usando window.matchMedia

    const mq = window.matchMedia('(max-width: 768px)');
    useEffect(() => {
    //initial check to toggle something on or off
    toggle();
    //returns true when window is <= 768px
    mq.addListener(toggle);
    //unmount cleanup handler
    return () => mq.removeListener(toggle);
    }, []);
    //toggle something based on matchMedia event
    const toggle = () => {
    if (mq.matches) {
    //do something here
    } else {
    //do something here
    }
    };

    .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.

  19. 0

    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

    • Tal vez de suministro código de ejemplo?

Dejar respuesta

Please enter your comment!
Please enter your name here