Time: 20200130
安装必要的包
yarn add axios
yarn add redux-thunk
配置中间件: redux-thunk
store.js
import { createStore, applyMiddleware } from 'redux'
import { rootReducer } from './rootReducer'
import thunk from 'redux-thunk'
import logger from 'redux-logger'
import { composeWithDevTools } from 'redux-devtools-extension'
const store = createStore(rootReducer,
composeWithDevTools( applyMiddleware(logger, thunk)
)
)
export default store
redux-thunk
也是一个中间件,需要通过applyMiddleware
使用。
异步Action Creator
修改userActions.js
import
{ FETCH_USER_REQUEST,
FETCH_USER_SUCCESS,
FETCH_USER_FAILURE
}
from './userTypes'
import axios from 'axios'
/**
* Action Creator接收数据,通过参数的方式接收,然后存到action对象中
* reducer不用操心数据的问题,只要定义好逻辑即可
* 即,reducer是纯函数
*/
// 三个Action Creator函数,均为同步Action
export const fetchUserRequest = () => {
return {
type: FETCH_USER_REQUEST
}
}
// 这些参数需要通过外部传入
export const fetchUserSuccess = users => {
return {
type: FETCH_USER_SUCCESS,
payload: users
}
}
export const fetchUserFailure = error => {
return {
type: FETCH_USER_FAILURE,
payload: error
}
}
// 异步Action Creator
// 被thunk接管,所以返回一个函数
// 返回的函数不要求是纯函数
export const fetchUserAsync = () => {
return (dispatch) => {
// 在真正读取数据前先告知要开始获取数据了
dispatch(fetchUserRequest)
axios.get('https://jsonplaceholder.typicode.com/users')
.then(response => {
// 分发到同步Action
const users = response.data
dispatch(fetchUserSuccess(users))
})
.catch(error => {
const errorMessage = error.message
dispatch(fetchUserFailure(errorMessage))
})
}
}
// 只要dispatch就可以把数据存储到action.payload
同步异步Action Creator都写在一起,同步Action Creator是为异步服务,最后只需要暴露异步Action Creator即可。
UserContainer.js
import React, { useEffect } from 'react'
import { connect } from 'react-redux'
import { fetchUserAsync } from '../redux'
// 解构props
function UserContainer({userData, fetchUsers}) {
// dispatch only once
useEffect(() => {
fetchUsers()
}, [])
return userData.loading
? <h2>Loading</h2>
: (userData.error
? <h2>{userData.error}</h2>
: (<div>
<h2>Users List</h2>
<div>
{userData && userData.users && userData.users.map(user => <p>{user.name}</p>)}
</div>
</div>))
}
const mapStateToProps = (state, ownProps) => {
return {
userData: state.user
}
}
const mapDispatchToProps = (dispatch, ownProps) => {
return {
fetchUsers: () => dispatch(fetchUserAsync())
}
}
export default connect(mapStateToProps,
mapDispatchToProps)
(UserContainer)
END.