it-swarm.com.de

Rendering-Reakt-Komponente nach der API-Antwort

Ich habe eine React-Komponente, die ich mithilfe der Dropbox-API mit Bildern füllen möchte. Der api-Teil funktioniert einwandfrei, aber die Komponente wird gerendert, bevor die Daten durchlaufen werden. Das Array ist also leer. Wie kann ich das Rendern der Komponente verzögern, bis die benötigten Daten vorhanden sind?

var fileList = [];
var images = [];
var imageSource = [];

class Foo extends React.Component {

 render(){
  dbx.filesListFolder({path: ''})
  .then(function(response) {
   fileList=response.entries;
   for(var i=0; i<fileList.length; i++){
    imageSource.Push(fileList[0].path_lower);
   }
   console.log(imageSource);
   })

  for(var a=0; a<imageSource.length; a++){
   images.Push(<img key={a} className='images'/>);
  }

  return (
   <div className="folioWrapper">
    {images}
   </div>
  );
 }
}

Danke für Ihre Hilfe!

7
r_cahill

Änderungen:

1. Führen Sie den API-Aufruf nicht innerhalb der Render-Methode aus, sondern verwenden Sie die componentDidMount-Lebenszyklus-Methode.

componentDidMount:

componentDidMount () wird sofort aufgerufen, nachdem eine Komponente .__ ist. montiert. Die Initialisierung, die DOM-Knoten erfordert, sollte hier ausgeführt werden. Wenn du Wenn Sie Daten von einem entfernten Endpunkt laden müssen, ist dies ein guter Ort für Instantiieren Sie die Netzwerkanfrage. Einstellungsstatus in dieser Methode wird ein erneutes Rendering auslösen.

2. Definieren Sie die Variable imageSource im Statusarray mit dem Anfangswert []. Sobald Sie die Antwort erhalten, die Sie mit setState erhalten, wird die Komponente mit den aktualisierten Daten automatisch erneut gerendert.

3. Verwenden Sie das State-Array, um die UI-Komponenten in der Render-Methode zu generieren.

4. Um das Rendern so lange zu halten, bis Sie die Daten nicht abgerufen haben, setzen Sie die Bedingung in die render-Methode. Überprüfen Sie die Länge des imageSource-Arrays, wenn die Länge Null ist und dann return null.

Schreibe es so:

class Foo extends React.Component {

    constructor(){
        super();
        this.state = {
            imageSource: []
        }
    }

    componentDidMount(){
        dbx.filesListFolder({path: ''})
          .then((response) => {
              let fileList = response.entries;
              this.setState({
                  imageSource: fileList
              });
          })
    }

    render(){
        if(!this.state.imageSource.length)
            return null;

        let images = this.state.imageSource.map((el, i) => (
            <img key={i} className='images' src={el.path_lower} />
        ))

        return (
            <div className="folioWrapper">
                {images}
            </div>
        );
    }
}
8
Mayank Shukla

Sie sollten den Status oder die Requisiten Ihrer Komponente verwenden, damit sie erneut angezeigt wird, wenn Daten aktualisiert werden. Der Aufruf von Dropbox sollte außerhalb der render-Methode erfolgen. Andernfalls müssen Sie die API jedes Mal aufrufen, wenn die Komponente erneut gerendert wird. Hier ist ein Beispiel, was Sie tun könnten.

class Foo extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      imageSource: []
    }
  }

  componentDidMount() {
    dbx.filesListFolder({ path: '' }).then(function(response) {
      const fileList = response.entries;

      this.setState({
        imageSource: fileList.map(file => file.path_lower);
      })
    });
  }

  render() {
    return (
      <div className="folioWrapper">
        {this.state.imageSource.map((image, i) => <img key={i} className="images" src={image} />)}
      </div>
    );
  }
}

Wenn noch keine Bilder vorhanden sind, wird ein leerer div auf diese Weise gerendert.

5
DonovanM

Zunächst sollten Sie den Zustand der Komponente und keine global definierten Variablen verwenden.

Um zu vermeiden, dass die Komponente mit einem leeren Array von Bildern angezeigt wird, müssen Sie eine bedingte Klasse zum Laden auf die Komponente anwenden und diese entfernen, wenn das Array nicht mehr leer ist.

0
Francisco Mateo