J'ai un problème trivial (je suppose) concernant le rendu dans React mais je ne peux pas le résoudre et je ne trouve aucune solution.

Mon problème est que j'ai un composant qui est wrapper pour certaines entrées. Quelque chose comme:

class MyWrapper extends Component {
  renderItems() {
    return (
        {this.props.items.map(item => (
         <ItemComponent item={item} />
        ))}
    );
  }

  renderMessage() {
    return (<p>No items to show</p>);
  }

  render() {
   <div>
     {this.props.length
        ? this.renderItems()
        : this.renderMessage()
     } 
   </div>
  }
}

Habituellement, j'obtiens this.props.items un tas d'éléments, donc le rendu de l'ensemble du thème prend du temps. C'est pourquoi je voudrais afficher un message comme Loading items... jusqu'à ce que le rendu de tous les éléments soit terminé. Ensuite, ce message devrait disparaître.

Merci d'avance pour votre aide!

3
Dominik Krzywiecki 13 avril 2018 à 22:42

3 réponses

Meilleure réponse

Ce ne sont que mes expériences comment faire - je suggère de prendre quelques idées et de les essayer vous-même, peut-être que cela vous mettra sur la bonne voie ou peut-être que c'est de l'argent

https://codesandbox.io/s/k2mpvkr2n7

L'idée principale est de mettre la liste dans un composant séparé et de changer l'état de chargement lors de son montage.

Pour les choses visuelles, je mets un setTimeout et ignore le tableau cow (:

1
Tomas Eglinskas 13 avril 2018 à 20:19

Voici une idée:

  1. Vous passez un accessoire de rappel à ItemComponent
  2. Ce rappel est appelé à partir de componentDidMount () de ItemComponent, pour le rendu initial, et de componentDidUpdate () pour les rendus suivants.
  3. Le rappel incrémente une variable d'état dans MyWrapper
  4. Chargement ... s'affiche lorsque cette variable d'état est égale à la longueur

Notez que la variable d'état qui compte les rendus doit être mise à jour en utilisant une fonction comme paramètre, pour vous assurer qu'elle est incrémentée correctement (voir this)

1
Yossi 13 avril 2018 à 20:48

Voici une solution rapide et sale. Idéalement, le concept sera ce que vous recherchez et vous pourrez le nettoyer à votre guise.

(De plus, je crois comprendre que le problème est que props.items est énorme et que la procédure de mappage prend simplement un certain temps)

class MyWrapper extends Component {
  constructor(props) {
    super(props);
    this.state = { items: [] }
  }

  componentDidMount() {
    this.setState({ items: this.createItemComponents() })
  }

  createItemComponents() {
    return this.props.items.length !== 0
      ? this.props.items.map(item => <ItemComponent item={item} />);
      : <p>No items to show</p>;
  }

  render() {
   <SomeLoadingIndicator active={this.state.items.length === 0} />

   <div>{this.state.items}</div>
  }
}
0
Sam 13 avril 2018 à 20:59