api 调用后应用程序状态未更新
Application state doesn't get updated after api call
我缺少关于异步调用在 react-redux 中工作方式的关键 step/concept。
目前,我可以进行 api 调用(也可以通过 chrome-dev-tools 查看正在 returned 的数据)但响应数据不是
体现在申请状态;这意味着测验对象的状态(默认情况下为空对象)不会更新。
我的期望是,当异步调用解决时,我会解析 quizReducer 中的响应,并 return 反映响应数据的新状态(不是变异状态)。
然而,每次调用时,更新后的状态 return 是一个空的测验对象(这是初始状态)。
我知道我错过了什么,但我不知道是什么;真的很感激一些 pointers/explanation。谢谢
该应用的 initialState/Preloaded 状态如下所示:
export default {
quizzes: [
{id: 0, name: "quiz_name2", completed: false, selected: false},
{id: 1, name: "quiz_name2", completed: false, selected: false}
],
quiz: { questions: {} }
};
相关减速器的设置:
import initialState from './initialState';
import quizConstants from '../constants/quizConstants';
const actionTypes = quizConstants.actions
// when app loads, user has not selected any quiz therefore
// initialState is an empty object
// here action is the payload we get when a quiz is selected (see QUIZ_SELETED action creator)
export default function quiz(state=initialState.quiz, action) {
switch(action.type){
// when a quiz is selected, return new state
case actionTypes.SELECT_QUIZ:
return Object.assign(
{},
state,
{
id: action.quiz.id,
name: action.quiz.name,
completed: action.quiz.completed,
selected: !action.quiz.selected,
fetching: action.quiz.fetching,
fetched: action.quiz.fetched,
questions: action.quiz.questions
}
)
case actionTypes.REQUEST_QUIZ:
return Object.assign(
{},
state,
{
id: action.quiz.id,
name: action.quiz.name,
completed: action.quiz.completed,
selected: !action.quiz.selected,
fetching: !action.quiz.fetching,
fetched: action.quiz.fetched,
questions: action.quiz.questions
}
)
case actionTypes.RECEIVE_QUIZ:
return Object.assign(
{},
state,
{
id: action.quiz.id,
name: action.quiz.name,
completed: action.quiz.completed,
selected: !action.quiz.selected,
fetching: action.quiz.fetching,
fetched: !action.quiz.fetched,
quiz: action.quiz.questions
}
)
default:
return state
}
};
index.js(rootreducer):
import { combineReducers } from 'redux';
import { routerReducer } from 'react-router-redux';
import quizzes from './quizzesReducer'
import quiz from './quizReducer';
export default combineReducers({
quizzes,
quiz,
routing: routerReducer
});
QuizActionCreators
import quizConstants from '../constants/quizConstants';
import { quizzesEndPoint } from '../constants/appConstants';
import axios from 'axios';
const actionTypes = quizConstants.actions
// select a quiz
export const selectQuiz = (quiz) => {
return {
type: actionTypes.SELECT_QUIZ,
quiz
}
};
const receiveQuiz = (quiz, data) => {
return {
type: actionTypes.RECEIVE_QUIZ,
quiz,
data
}
};
// call when componentWillMount
export const fetchQuiz = (quiz) => {
console.log("Make an api request here")
const url = quizzesEndPoint.concat(quiz.name)
axios.get(url)
.then(response => response.data)
.then(data => receiveQuiz(quiz, data))
}
export default { selectQuiz, fetchQuiz};
在您的 QuizActionCreator
中,您的 fetchQuiz
正在调用 receiveQuiz
并传递 quiz
和 data
作为您的参数,后者具有来自服务器。我在你的减速器中没有看到你将 action.data
设置为状态的任何部分。
尝试将 RECEIVE_QUIZ
的处理程序添加到 quizzesReducer
和 return 的 action.data
状态。
//quizzesReducer.js
export default function (state = initialState.quizzes, action){
...
if (action.type === actionTypes.RECEIVE_QUIZ) {
return action.data
}
...
};
我缺少关于异步调用在 react-redux 中工作方式的关键 step/concept。
目前,我可以进行 api 调用(也可以通过 chrome-dev-tools 查看正在 returned 的数据)但响应数据不是 体现在申请状态;这意味着测验对象的状态(默认情况下为空对象)不会更新。
我的期望是,当异步调用解决时,我会解析 quizReducer 中的响应,并 return 反映响应数据的新状态(不是变异状态)。
然而,每次调用时,更新后的状态 return 是一个空的测验对象(这是初始状态)。
我知道我错过了什么,但我不知道是什么;真的很感激一些 pointers/explanation。谢谢
该应用的 initialState/Preloaded 状态如下所示:
export default {
quizzes: [
{id: 0, name: "quiz_name2", completed: false, selected: false},
{id: 1, name: "quiz_name2", completed: false, selected: false}
],
quiz: { questions: {} }
};
相关减速器的设置:
import initialState from './initialState';
import quizConstants from '../constants/quizConstants';
const actionTypes = quizConstants.actions
// when app loads, user has not selected any quiz therefore
// initialState is an empty object
// here action is the payload we get when a quiz is selected (see QUIZ_SELETED action creator)
export default function quiz(state=initialState.quiz, action) {
switch(action.type){
// when a quiz is selected, return new state
case actionTypes.SELECT_QUIZ:
return Object.assign(
{},
state,
{
id: action.quiz.id,
name: action.quiz.name,
completed: action.quiz.completed,
selected: !action.quiz.selected,
fetching: action.quiz.fetching,
fetched: action.quiz.fetched,
questions: action.quiz.questions
}
)
case actionTypes.REQUEST_QUIZ:
return Object.assign(
{},
state,
{
id: action.quiz.id,
name: action.quiz.name,
completed: action.quiz.completed,
selected: !action.quiz.selected,
fetching: !action.quiz.fetching,
fetched: action.quiz.fetched,
questions: action.quiz.questions
}
)
case actionTypes.RECEIVE_QUIZ:
return Object.assign(
{},
state,
{
id: action.quiz.id,
name: action.quiz.name,
completed: action.quiz.completed,
selected: !action.quiz.selected,
fetching: action.quiz.fetching,
fetched: !action.quiz.fetched,
quiz: action.quiz.questions
}
)
default:
return state
}
};
index.js(rootreducer):
import { combineReducers } from 'redux';
import { routerReducer } from 'react-router-redux';
import quizzes from './quizzesReducer'
import quiz from './quizReducer';
export default combineReducers({
quizzes,
quiz,
routing: routerReducer
});
QuizActionCreators
import quizConstants from '../constants/quizConstants';
import { quizzesEndPoint } from '../constants/appConstants';
import axios from 'axios';
const actionTypes = quizConstants.actions
// select a quiz
export const selectQuiz = (quiz) => {
return {
type: actionTypes.SELECT_QUIZ,
quiz
}
};
const receiveQuiz = (quiz, data) => {
return {
type: actionTypes.RECEIVE_QUIZ,
quiz,
data
}
};
// call when componentWillMount
export const fetchQuiz = (quiz) => {
console.log("Make an api request here")
const url = quizzesEndPoint.concat(quiz.name)
axios.get(url)
.then(response => response.data)
.then(data => receiveQuiz(quiz, data))
}
export default { selectQuiz, fetchQuiz};
在您的 QuizActionCreator
中,您的 fetchQuiz
正在调用 receiveQuiz
并传递 quiz
和 data
作为您的参数,后者具有来自服务器。我在你的减速器中没有看到你将 action.data
设置为状态的任何部分。
尝试将 RECEIVE_QUIZ
的处理程序添加到 quizzesReducer
和 return 的 action.data
状态。
//quizzesReducer.js
export default function (state = initialState.quizzes, action){
...
if (action.type === actionTypes.RECEIVE_QUIZ) {
return action.data
}
...
};