2016-08-01 29 views
4

Ich bin neu in React und Redux.Call Rendite Put() in einem Erfolg Callback

Ich verwende react-redux, um den AWS Cognito-Dienst aufzurufen, der ein Objekt mit einem Erfolgs- und Fehlerrückruf entgegennimmt. Ich bekomme meinen JWT von AWS Cognito zurück, wenn ich console.log innerhalb meines Erfolgsrückrufs einsetze. Wie kann ich jedoch yield put() innerhalb dieses Rückrufs, da es keine Generatorfunktion ist (function*).

Hier einige Code:

export function* getAWSToken(){ 
    // username, password and userPool come from react state 
    // not showing code for brevity. 

    const userData = { 
     Username: username, 
     Pool: userPool, 
    }; 
    const authenticationData = { 
    Username : username, 
    Password : password, 
    }; 

    const cognitoUser = new AWSCognito.CognitoIdentityServiceProvider.CognitoUser(userData); 
    const authenticationDetails = new AWSCognito.CognitoIdentityServiceProvider.AuthenticationDetails(authenticationData); 

    // This here is the callback 
    cognitoUser.authenticateUser(authenticationDetails, { 
    onSuccess(result){ 
     yield put(cognitoTokenObtained(result.getIdToken().getJwtToken()) 
    }, 
    onFailure(err){} 
    }); 
} 
+0

Warum eine Generatorfunktion verwenden? Jedes Mal, wenn Sie 'getAWSToken' aufrufen, gibt Ihnen Cognito ein neues Token, verbessert ein Generator die Dinge? –

+0

Wie bereits erwähnt, bin ich neu zu React und Redux, also befolge ich Beispiele. Es scheint, dass überall dort, wo Redux-Saga verwendet wird, eine Generatorfunktion verwendet wird. Sollte dies nicht der Fall sein, informieren Sie bitte. –

+0

Hmm, es scheint mir zu komplex. Sie könnten einfach eine normale Funktion verwenden, einen Callback an "getAWSToken (yourCallback)" übergeben und dann diese Funktion in 'onSuccess' wie' callback (result) 'aufrufen. Aber wenn es einen 'redux-saga'-spezifischen Grund für die Verwendung von Generatorfunktionen gibt, dann würde ich nicht etwas vorschlagen wollen, das' redux-saga 'bricht. –

Antwort

4

Wenn Sie redux-Saga verwenden (was super ist), können Sie die call effect verwenden, um einen asyc Rückruf wie cognitoUser.authenticateUser in eine Reihe von Anweisungen zur Transformation zu sein ausgeführt von der Middlewhere.

Wenn die Middleware den Aufruf auflöst, wird der Generator zur nächsten Yield-Anweisung weitergeleitet. Sie können das Rückgabeergebnis einer Variablen zuweisen, die Sie dann mit einem PUT-Effekt in Ihrem Status platzieren können.

export function* getAWSToken(){ 
    // username, password and userPool come from react state 
    // not showing code for brevity. 

    const userData = { 
     Username: username, 
     Pool: userPool, 
    }; 
    const authenticationData = { 
    Username : username, 
    Password : password, 
    }; 

    const cognitoUser = new AWSCognito.CognitoIdentityServiceProvider.CognitoUser(userData); 
    const authenticationDetails = new AWSCognito.CognitoIdentityServiceProvider.AuthenticationDetails(authenticationData); 

    // Note: since you're invoking an object method 
    // you'll want to pass the object's context (this) with the call via an array 

    const token = yield apply(cognitoUser, cognitoUser.authenticateUser, [authenticationDetails, { onSuccess(response){return response}, onFailure(){} }]); 

    yield put(cognitoTokenObtained(token.getIdToken().getJwtToken()); 
} 

Es gibt auch 10, die ich sehr empfehlen kann.

Edit: Sie haben etwas Code für die Kürze weggelassen, aber ich würde sehr empfehlen, den Code innerhalb des Generators in Try Catch zu wickeln, da Sie auf externe IO von einer API abhängen.

+0

Vielen Dank für Ihr Beispiel und Tutorial Link, ich habe mehr über 'call/put' gelernt, dann hatte ich vorher gewusst; Allerdings habe ich immer noch ein kleines Problem mit dem von Ihnen bereitgestellten Beispiel. Wenn ich callitoUser.authenticateUser verwende, beschwert sich die Cognito-JS-Bibliothek von AWS mit 'TypeError: Kann die Eigenschaft 'getUserPoolId' von 'undefined' nicht lesen, was mich zu der Annahme verleitet, dass ich die Parameter nicht korrekt in 'call()' übergebe Methode. –

+0

Wenn ich es herausgefunden habe, musste ich den Kontext in cognitoUser übergeben. Also, mein Anruf sieht so aus. 'const token = yield call ([cognitoUser, cognitoUser.authenticateUser], authenticationDetails);' –

+0

Ah! Entschuldigung, das habe ich nicht verstanden! Ich werde die Antwort für zukünftige Zuschauer aktualisieren. Danke Patrick! –