2017-07-04 6 views
2

Ich habe eine Reaktionskomponente, die ich mit Bildern mit der Dropbox API füllen möchte. Der api-Teil funktioniert gut, aber die Komponente wird gerendert, bevor die Daten durch & kommen, so dass das Array leer ist. Wie kann ich das Rendering der Komponente verzögern, bis sie die benötigten Daten hat?Rendering-Komponente nach API-Antwort

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> 
); 
} 
} 

Vielen Dank für Ihre Hilfe!

+0

würde ich nur, dass die Komponente montieren, wenn Sie die Bilder haben. Wer also diese Komponente (die Eltern) mountet, sollte die Bilder holen und dann die Komponente mounten. – MinusFour

+0

Sie sollten nicht alle diese Arbeit innerhalb Ihrer 'render' Methode tun. Wo wechselst du den Staat?Die Komponente wird nach dem Aktualisieren des Status gerendert. – DonovanM

Antwort

0

Zunächst sollten Sie die component's state verwenden und nicht global definierte Variablen verwenden.

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

+0

Das ist das Problem, um das ich mich bemühe, zu verstehen - wie man die Komponente _know_ aktivieren kann, wenn das Array nicht mehr leer ist. –

+1

Siehe Mayank Shukla Antwort. –

1

Sie sollten den Status oder die Requisiten Ihrer Komponente verwenden, damit sie beim Aktualisieren der Daten erneut gerendert wird. Der Aufruf von Dropbox sollte außerhalb der render-Methode ausgeführt werden, da sonst die API bei jeder erneuten Wiedergabe der Komponente ausgelöst wird. Hier ist ein Beispiel dafür, 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 sind, es wird nur eine leere div auf diese Weise machen.

2

Änderungen:

1. Sie innen machen die api Call-Methode nicht tun, denn das componentDidMount Lifecycle-Methode verwenden.

componentDidMount:

componentDidMount() aufgerufen wird, unmittelbar nachdem ein Bauteil montiert. Initialisierung, die DOM-Knoten erfordert, sollte hier gehen. Wenn Sie Daten von einem Remote-Endpunkt laden müssen, ist dies ein guter Ort, um die Netzwerkanforderung instanziieren . Wenn in dieser Methode der Status gesetzt wird, wird ein erneutes Rendering ausgelöst.

2. Definieren Sie die imageSource Variable im Zustand Array mit Anfangswert [], sobald Sie das Antwort-Update zu erhalten, die mit aktualisierten Daten setState, wird es automatisch wieder macht die Komponente.

3. Verwenden Sie das Statusarray, um die ui-Komponenten in der Rendermethode zu generieren.

4. die Wiedergabe zu halten, bis Sie die Daten nicht erhalten haben, setzen Sie den Zustand im Inneren render Methode, um die Länge des imageSource Array prüfen, ob Länge Null ist dann return null.

schreiben es so:

class Foo extends React.Component { 

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

    componentDidMount(){ 
     dbx.filesListFolder({path: ''}) 
      .then(function(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> 
     ); 
    } 
} 
Verwandte Themen