首页 > 解决方案 > 如何在 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。

标签: javascriptnode.jsredux

解决方案


您需要在默认情况下返回现有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;   
    }
}

推荐阅读