2016-02-10 5 views
5

Hey Leute haben hier ein Problem mit Methoden feuern nicht in der richtigen Reihenfolge. Ich kann nicht herausfinden, wie die this.props.history.pushState(null, '/authors'); in der saveAuthor() -Methode warten.React Router - Geschichte Feuer zuerst eher warten

Hilfe wird sehr geschätzt.

import React, { Component } from 'react'; 
import AuthorForm from './authorForm'; 
import { History } from 'react-router'; 

const source = 'http://localhost:3000/authors'; 


// History Mixin Component Hack 
function connectHistory (Component) { 
    return React.createClass({ 
    mixins: [ History ], 
    render() { 
     return <Component {...this.props} history={this.history}/> 
    } 
    }) 
} 


// Main Component 
class ManageAuthorPage extends Component { 
    state = { 
    author: { id: '', firstName: '', lastName: '' } 
    }; 

    setAuthorState(event) { 
    let field = event.target.name; 
    let value = event.target.value; 
    this.state.author[field] = value; 
    return this.setState({author: this.state.author}); 
    }; 

    generateId(author) { 
    return `${author.firstName.toLowerCase()}-${author.lastName.toLowerCase()}` 
    }; 

// Main call to the API 

    postAuthor() { 
    fetch(source, { 
     method: 'post', 
     headers: { 
     'Accept': 'application/json', 
     'Content-Type': 'application/json' 
     }, 
     body: JSON.stringify({ 
      id: this.generateId(this.state.author), 
      firstName: this.state.author.firstName, 
     lastName: this.state.author.lastName 
     }) 
    }); 
    }; 

    // Calling Save author method but the this.props.history goes first rather than this.postAuthor(); 

    saveAuthor(event) { 
    event.preventDefault(); 
    this.postAuthor(); 
    this.props.history.pushState(null, '/authors'); 
    }; 

    render() { 
    return (
     <AuthorForm 
     author={this.state.author} 
     onChange={this.setAuthorState.bind(this)} 
     onSave={this.saveAuthor.bind(this)} 
     /> 
    ); 
    } 
} 



export default connectHistory(ManageAuthorPage) 

Antwort

2

Abruf ist eine asynchrone Funktion. Die Ausführung wird in der nächsten Zeile fortgesetzt, bevor die Anforderung abgeschlossen ist. Sie müssen den Code in die Warteschlange stellen, damit er nach dem Ende der Anfrage ausgeführt werden kann. Der beste Weg, dies zu tun wäre, dass Ihre postAuthor-Methode das Versprechen zurückgibt und dann die Methode .then des Versprechens im Aufrufer verwendet.

class ManageAuthorPage extends Component { 
// ... 
    postAuthor() { 
    return fetch(source, { 
     method: 'post', 
     headers: { 
     'Accept': 'application/json', 
     'Content-Type': 'application/json' 
     }, 
     body: JSON.stringify({ 
      id: this.generateId(this.state.author), 
      firstName: this.state.author.firstName, 
     lastName: this.state.author.lastName 
     }) 
    }); 
    }; 

    saveAuthor(event) { 
    event.preventDefault(); 
    this.postAuthor().then(() => { 
     this.props.history.pushState(null, '/authors'); 
    }); 
    }; 
// ... 
} 

Wenn Sie einen Transpiler verwenden, die ES7 Asynchron-Funktionen unterstützt, dann können Sie auch in Ihrer saveAuthor Methode tun dies, das lesen gleichwertig und einfacher ist:

async saveAuthor(event) { 
    event.preventDefault(); 
    await this.postAuthor(); 
    this.props.history.pushState(null, '/authors'); 
    }; 
+0

Ja, irgendwie habe ich das herausgefunden, aber danke für die asynchrone ES7-Methode. Ich habe ein paar Sachen gelesen und habe es nicht verstanden, aber die paar Codezeilen haben mir gezeigt, wie es funktioniert. Prost Kumpel. – Khpalwalk

1

So ist dies, weil Ihre postAuthor Methode einen asynchronen Aufruf zu fetch() innerhalb von ihm hat. Dies ist eine Zeit, in der Sie eine Funktion als Rückruf an die Funktion übergeben und dann diese Funktion innerhalb des Callbacks "Completion" des Aufrufs fetch aufrufen möchten. Der Code würde etwa so aussehen:

postAuthor(callback) { 
    fetch(source, { 
    /* Methods, headers, etc. */ 
    },() => { 
    /* Invoking the callback function that you passed */ 
    callback(); 
    }); 
); 

saveAuthor(event) { 
    event.preventDefault(); 
    /* Pass in a function to be invoked from within postAuthor when it is complete */ 
    this.postAuthor(() => { 
    this.props.history.pushState(null, '/authors'); 
    }); 
}; 
+0

ich etwas tat Art ähnlich aber trotzdem danke. – Khpalwalk