javascript - 如何在 redux-thunk 中进行多个 api 调用?
问题描述
这是我尝试过的。
const redux = require('redux')
const thunkMiddleware = require('redux-thunk').default
const axios = require('axios')
const reduxLogger = require('redux-logger')
const createStore = redux.createStore
const applyMiddleware = redux.applyMiddleware
const combineReducers = redux.combineReducers
const userState = {
loading: false,
users: [],
error: ''
}
const todoState = {
loading: false,
todos: [],
error: ''
}
const FETCH_USERS_REQUEST = 'FETCH_USERS_REQUEST'
const FETCH_USERS_SUCCESS = 'FETCH_USERS_SUCCESS'
const FETCH_USERS_FAILURE = 'FETCH_USERS_FAILURE'
const FETCH_TODOS_REQUEST = 'FETCH_TODOS_REQUEST'
const FETCH_TODOS_SUCCESS = 'FETCH_TODOS_SUCCESS'
const FETCH_TODOS_FAILURE = 'FETCH_TODOS_FAILURE'
const fetchUserRequest = () => {
return {
type: FETCH_USERS_REQUEST
}
}
const fetchUserSuccess = users => {
return {
type: FETCH_USERS_SUCCESS,
payload: users
}
}
const fetchUserFailure = error => {
return {
type: FETCH_USERS_FAILURE,
payload: error
}
}
const fetchTodosRequest = () => {
return {
type: FETCH_TODOS_REQUEST
}
}
const fetchTodosSuccess = users => {
return {
type: FETCH_TODOS_SUCCESS,
payload: users
}
}
const fetchTodosFailure = error => {
return {
type: FETCH_TODOS_FAILURE,
payload: error
}
}
const userReducer = (state = userState, action) => {
switch(action.type){
case FETCH_USERS_REQUEST:
return {
...state,
loading: true
}
case FETCH_USERS_SUCCESS:
return {
error: '',
loading: false,
users: action.payload
}
case FETCH_USERS_SUCCESS:
return {
users: [],
loading: false,
error: action.payload
}
default:
return
}
}
const todosReducer = (state = todoState, action) => {
switch(action.type){
case FETCH_TODOS_REQUEST:
return {
...state,
loading: true
}
case FETCH_TODOS_SUCCESS:
return {
error: '',
loading: false,
todos: action.payload
}
case FETCH_TODOS_SUCCESS:
return {
todos: [],
loading: false,
error: action.payload
}
default:
return
}
}
const fetchUsers = () => {
return function (dispatch) {
dispatch(fetchUserRequest())
axios.get(`https://jsonplaceholder.typicode.com/users`)
.then(resp => {
let users = resp.data.map(user => user.name)
dispatch(fetchUserSuccess(users))
})
.catch(err => {
dispatch(fetchUserFailure(err.message))
})
}
}
const fetchTodos = () => {
return function (dispatch) {
dispatch(fetchTodosRequest())
axios.get(`https://jsonplaceholder.typicode.com/todos`)
.then(resp => {
let todos = resp.data
dispatch(fetchTodosSuccess(todos))
})
.catch(err => {
dispatch(fetchTodosFailure(err.message))
})
}
}
const rootReducer = combineReducers({
users: userReducer,
todos: todosReducer
})
const store = createStore(rootReducer, applyMiddleware(thunkMiddleware))
console.log('initial state', store.getState())
store.subscribe(() => {console.log(store.getState())})
store.dispatch(fetchUsers())
store.dispatch(fetchTodos())
我收到以下错误。错误:关键“用户”的切片缩减器在初始化期间返回未定义。如果传递给 reducer 的状态未定义,则必须显式返回初始状态。初始状态可能不是未定义的。如果你不想为这个 reducer 设置值,你可以使用 null 而不是 undefined。
解决方案
您需要在默认情况下返回现有return state
而不是return
todoreducer
const todosReducer = (state = todoState, action) => {
switch(action.type){
case FETCH_USERS_REQUEST:
return {
...state,
loading: true
}
case FETCH_USERS_SUCCESS:
return {
error: '',
loading: false,
users: action.payload
}
case FETCH_USERS_SUCCESS:
return {
users: [],
loading: false,
error: action.payload
}
default:
return state; // return state which has initial state values
}
}
用户减速器
const userReducer = (state = userState, action) => {
switch(action.type){
case FETCH_USERS_REQUEST:
return {
...state,
loading: true
}
case FETCH_USERS_SUCCESS:
return {
error: '',
loading: false,
users: action.payload
}
case FETCH_USERS_SUCCESS:
return {
users: [],
loading: false,
error: action.payload
}
default:
return state;
}
}
推荐阅读
- r - 使用特定标准消除 R 中的重复项
- amazon-web-services - 从 ECS Fargate 容器发送 /var/log (syslog) 到 Cloudwatch
- python - 尝试将 txt 文件读取为 csv 但遇到问题
- flutter - 异步调用以从路由参数中获取一些数据
- flask - Flask-Socketio:WebSocket 握手期间出错:意外的响应代码:503 & WebSocket 在建立连接之前关闭
- javascript - 使用 React 访问 API 时出现未经授权的错误
- vue.js - 渲染时设置 vue-swatches 子组件的颜色
- airflow - 有没有办法通过 SimpleHttpOperator 在 Airflow 中通过 REST 上传文件?
- vue.js - Vue路由器,无法读取未定义的属性“推送”
- javascript - 函数返回自身,意外行为