2017-07-05 6 views
0

Es ist meine erste Erfahrung mit React, Redux und ich bin total verloren. Das Problem ist meine Aktion:React, Redux und Axios - versuchen API Aufruf zu machen

import axios from 'axios'; 
import { FETCH_MOVIE } from '../constants/actionTypes'; 
const API_KEY = <API_KEY>; 
const ROOT_URL = `<API_URL>`; 


export function fetchMovies(pop){ 

    const url = `${ROOT_URL}?api_key=${API_KEY}&sort_by=${pop}`; 
    axios.get(url) 
    .then(function (response) { 
    console.log("response is",response) 
    }) 
    .catch(function (error) { 
    console.log(error); 
    }); 

    return{ 
    type: FETCH_MOVIE, 
    payload: response.data 
    }; 
} 

Screenshot of Console.log

Auf console.log es ganz gut scheint - ich kann sehen, die Antwort die Daten, die ich brauche. Aber wenn ich versuche, response.data an Payload zu senden, gibt es den Fehler zurück - Antwort ist nicht definiert. Was mache ich falsch?

Ps.s. Ich habe auch versucht, const result = [] und dann result = [... response.data] zu erstellen. Der Fehler war - SyntaxError: "result" ist schreibgeschützt.

+0

Sie müssen wahrscheinlich Ihre Rückkehr Erklärung in der .then Teil verschieben – gianni

+0

@ Gianni danke für die Antwort! Ich habe versucht, es zu verschieben, der Fehler war "Aktionen müssen einfache Objekte sein." – Polina

+0

Ihre Funktion wird ausgeführt, bevor die Antwort zurückgegeben wird. Daher müssen Sie die Middleware gemäß @loelsonk answer verwenden. – gianni

Antwort

1

Der Fehler const ist, weil das Ergebnis eine Variable ist, die sich im Laufe der Ausführung ändert, müssen Sie "let" und nicht "const" verwenden.

Jetzt, für die Behebung, Antwort ist nicht definiert kommt von der letzten Rückkehr. Ein guter Ansatz wäre, anstatt die Aktion für diese Funktion fetchMovies zurückzugeben, sollten Sie eine neue Aktion versenden, z. B. dispatch (fetchMoviesSuccess (Nutzlast)) anstelle von "console.log (" Antwort ist ", Antwort)" Senden Sie eine Aktion, die den Reduzierer auslöst, und aktualisieren Sie den Status der App.

1

Das Problem mit Ihrem Code ist, dass die Antwort zu der Zeit, die Sie zurückgeben, noch nicht definiert ist, da dieser Code synchron bis zur Rückgabeanweisung ausgeführt wird. Wie Sie sehen können, ist die Antwort definiert in console.log("response is",response) Also hier ist, wo Sie Ihre eigentliche Magie return tun müssen, aber auf andere Weise.

Sie können Redux-Thunk verwenden, um diese Dinge zu tun, weil dies Redux Async ist. Aber wie ich fühle, dass du ein Anfänger bist, benutze den einfacheren Weg und lies redux-thunk oder redux-promise. Wenn Sie das Gefühl haben, dass Ihr Projekt dies braucht, dann gehen Sie einen.

//try to make the caller pass this.props.dispatch as param 
export function fetchMovies(dispatch, pop){ 
    const url = `${ROOT_URL}?api_key=${API_KEY}&sort_by=${pop}`; 
    axios.get(url) 
    .then(function (response) { 
    // only here is response define so use dispatch to triger another action (fetched data with response) 
    dispatch({ 
     type: FETCH_MOVIE, 
     payload: response.data 
    }) 
    }) 
    .catch(function (error) { 
    //if you had a loader state, you call also toggle that here with erro status 
    console.log(error); 
    }); 
} 

//now on the caller (onClick for instance) do this instead 
fetchMovies(this.props.dispatch, pop) 

Wie Sie von @loelsonk Antwort sehen können. Wenn Sie redux-thunk verwenden, müssen Sie den Versand des Anrufers redux-thunk nicht für Sie übernehmen. Beachten Sie aber auch, wie Sie zurückkehren würden und anonyme Pfeilfunktionen, die den Versand als Parameter akzeptieren.

1

Sie führen async Anfrage mit Axios. Sie sollten Ihre Aktion mit redux-thunk versenden. Installation ist einfach, lesen Sie mehr über thunk here.

dann Ihre Aktion sollte wie folgt aussehen:

export function fetchMovies(pop) { 
    return dispatch => { 
    const url = `${ROOT_URL}?api_key=${API_KEY}&sort_by=${pop}`; 
    axios.get(url) 
    .then(function (response) { 
     console.log("response is",response); 

     dispatch({ 
     type: FETCH_MOVIE, 
     payload: response.data 
     }); 

    }) 
    .catch(function (error) { 
     console.log(error); 
     // You can dispatch here error 
     // Example 
     dispatch({ 
     type: FETCH_MOVIE_FAILED, 
     payload: error 
     }); 
    }); 

    } 
} 
1

Sie redux Versprechen Middleware nutzen können. Ich habe das in meinem neuen Projekt verwendet. Es ist sehr einfach und hält unseren Code und Zustand überschaubar.

Für jeden async Aktion Versand Versendungen es

$action_type_PENDING unmittelbar nach unserer Aktion Versand, $action_type_FULFILLED wenn Erfolg api Anruf, $action_type_REJECTED wenn api Anruffehler

Siehe https://github.com/pburtchaell/redux-promise-middleware

Beispiel aus meinem Projekt Dokumentations- -

Ihre Aktion ist

export function getQuestions() { 
    return { 
     type: types.GET_QUESTIONS, 
     payload: axios.get('http://localhost:3001/questions') 
    }; 
} 

Minderer ist

const initialState = { 
    isLoading: false, 
    questions: [] 
}; 

const questions = (state = initialState.questions, action) => { 
    switch(action.type) { 
     case types.GET_QUESTIONS_FULFILLED: 
      return [...action.payload.data]; 

     default: return state; 
    } 
}; 

Für Lader Anzeige während api Anruf wir

const isLoading = (state = initialState.isLoading, action) => { 
    switch(action.type) { 
     case (action.type.match(/_PENDING/) || {}).input: 
      return true; 

     case (action.type.match(/_FULFILLED/) || {}).input: 
      return false; 

     default: return state; 
    } 
}; 

mir folgenden Minderer Kommentar, wenn Sie auf dem oberen Sachen noch weitere Informationen benötigen können.

Verwandte Themen