web-dev-qa-db-fra.com

Comment obtenir la taille (hauteur/largeur) d'un composant de réaction avant le rendu?

J'ai un composant de réaction qui doit connaître ses dimensions à l'avance, avant de se rendre.

Lorsque je créais un widget dans jQuery, je pouvais juste utiliser $('#container').width() et obtenir la largeur du conteneur à l'avance lorsque je construisais mon composant.

<div id='container'></div>

les dimensions de ces conteneurs sont définies en CSS, ainsi que de nombreux autres conteneurs sur la page. Qui définit la hauteur, la largeur et l'emplacement des composants dans React? Je suis habitué à ce que CSS le fasse et puisse y accéder. Mais dans React, il semble que je ne puisse accéder à ces informations qu'après le rendu du composant.

4
foreyez

Comme il a déjà été mentionné, vous ne pouvez obtenir aucune dimension d'élément avant son rendu au DOM. Ce que vous pouvez faire dans React consiste à ne restituer qu'un élément conteneur, puis à obtenir sa taille dans componentDidMount, puis à restituer le reste du contenu.

J'ai fait un exemple de travail .

Veuillez noter que l'utilisation de setState dans componentDidMount est un anti-motif, mais dans ce cas, c'est bien, car c'est exactement ce que nous essayons d'atteindre.

À votre santé!

Code:

import React, { Component } from 'react';

export default class Example extends Component {
  state = {
    dimensions: null,
  };

  componentDidMount() {
    this.setState({
      dimensions: {
        width: this.container.offsetWidth,
        height: this.container.offsetHeight,
      },
    });
  }

  renderContent() {
    const { dimensions } = this.state;

    return (
      <div>
        width: {dimensions.width}
        <br />
        height: {dimensions.height}
      </div>
    );
  }

  render() {
    const { dimensions } = this.state;

    return (
      <div className="Hello" ref={el => (this.container = el)}>
        {dimensions && this.renderContent()}
      </div>
    );
  }
}
7
Stanko

Vous ne pouvez pas. Pas fiable, de toute façon. Ceci est une limitation du comportement du navigateur en général, pas de la réaction.

Lorsque vous appelez $('#container').width(), vous interrogez la largeur d'un élément que a rendu dans le DOM. Même dans jQuery, vous ne pouvez pas vous en sortir.

Si vous avez absolument besoin de la largeur d'un élément avant qu'il rendes , vous devrez l'estimer. Si vous devez mesurer avant d'être visible , vous pouvez le faire tout en appliquant visibility: hidden, ou le restituer quelque part de manière discrète sur la page, puis le déplacer après la mesure.

3
Litty

Comme indiqué, il s'agit d'une limitation des navigateurs - ils rendent en une fois et "dans un fil" (du point de vue de JS) entre votre script qui manipule le DOM et entre l'exécution des gestionnaires d'événements. Pour obtenir les dimensions après avoir manipulé/chargé le DOM, vous devez céder (laisser votre fonction), laisser le navigateur afficher et réagir à certains événements indiquant que le rendu est effectué. 

Mais essayez cette astuce:
Vous pouvez essayer de définir CSS display: hidden; position: absolute; et de le limiter à un cadre de sélection invisible pour obtenir la largeur souhaitée. Ensuite, cédez et, une fois le rendu terminé, appelez $('#container').width().

L'idée est la suivante: puisque display: hidden fait que l'élément occupe l'espace qu'il prendrait s'il était visible, le calcul doit être effectué à l'arrière-plan . Je ne suis pas sûr si cela peut être qualifié de "avant rendu".


Avertissement:
Je n'ai pas essayé, alors laissez-moi savoir si cela a fonctionné.
Et je ne sais pas comment cela se fondrait avec React.

0
Ondra Žižka