这是我第一次体验React,Redux和我完全迷失了。问题是我的行动:
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
};
}
在Console.log上看起来很好 - 我可以看到响应有我需要的数据。但是当我尝试将response.data发送到有效负载时,它会返回错误 - 未定义响应。我究竟做错了什么?
P.S。我还尝试创建const result = []而不是result = [... response.data]。错误是 - SyntaxError:&#34;结果&#34;是只读的
答案 0 :(得分:1)
const错误是因为,结果是一个在执行过程中发生变化的变量,你必须使用'let'而不是'const'。
现在,对于修复,未定义响应来自最后一次返回。一个好的方法是,不应该在这个函数fetchMovies上返回动作,而是应该调度一个新的动作,例如dispatch(fetchMoviesSuccess(payload))而不是“console.log(”response is“,response)”,这将是调度将触发减速器的动作,然后更新应用程序的状态。
答案 1 :(得分:1)
您的代码的问题是,当您返回时,响应仍未定义,因为此代码同步运行直到return语句。
如您所见,响应在<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="map-canvas"></div>
中定义
所以这就是你需要用你的实际魔法console.log("response is",response)
但另一种方式。
你可以使用redux-thunk来做这些事情,因为这是redux async。但是我觉得你是我见过的代码的初学者,只需使用更简单的方法并阅读return
或redux-thunk
。如果你认为你的项目需要这个,那就去吧。
redux-promise
正如你从@loelsonk的回答中看到的那样。如果您使用//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)
,则无需为调用者redux-thunk
传递调度。但是还要注意你将如何返回以及接受调度作为参数的匿名箭头函数。
答案 2 :(得分:1)
您正在使用axios执行async
请求。您应该使用redux-thunk
发送您的操作。安装很简单,请阅读有关thunk here的更多信息。
然后你的行动应该是这样的:
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
});
});
}
}
答案 3 :(得分:1)
您可以使用redux promise中间件。我在我的新项目中使用了这个。它非常简单,可以使我们的代码和状态易于管理。
对于每个异步操作调度,它都会调度
我们的行动发送后立即<{$action_type_PENDING
{1}}如果api呼叫成功,$action_type_FULFILLED
如果api呼叫失败
请参阅文档 - https://github.com/pburtchaell/redux-promise-middleware
我的项目示例 -
你的行动是
$action_type_REJECTED
reducer是
export function getQuestions() {
return {
type: types.GET_QUESTIONS,
payload: axios.get('http://localhost:3001/questions')
};
}
为了在api调用时显示加载器,我们可以使用以下reducer
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;
}
};
如果您需要有关上述内容的更多详细信息,请评论我。