1. File directory
2.state.js
export default {
areaIndex: 0,
token: {
accessToken: '',
idToken: '',
refreshToken: ''
}
}
3.index.js
Redux provides createStore
this function to generate Store.
createStore
The function takes another function as an argument and returns the newly generated Store object.
import { applyMiddleware, createStore } from 'redux'
// 中间件,用于异步action
import thunk from 'redux-thunk'
// 引入reducer
import reducers from './reducers.js'
// 创建store实例
let store = createStore(
reducers,
applyMiddleware(thunk)
)
export default store
4.actions.js
Action is an object. One of type
the attributes is required, indicating the name of the Action. Other properties can be set freely.
store.dispatch()
It is the only way for View to issue Action.
import Amplify, { Auth } from 'aws-amplify';
//同步action
export const AmplifyConfig = {
userPoolId: 'us-east-1_JZmBbVIcu',
userPoolWebClientId: '6agh327ji8qbf7aodopkhsh4o6'
};
Amplify.configure(AmplifyConfig);
export function setAreaIndex (data) {
return {
type: 'SET_AREA_INDEX', data
}
}
//异步action
export function loadToken(username,password) {
// 用 thunk 中间件解释:
return function(dispatch, getState) {
dispatch({
type: 'TOKEN_REQUEST'
})
// 异步分发原味 action
Auth.signIn(username, password).then(
response =>{
let token = response.signInUserSession
const {accessToken, idToken, refreshToken} = {accessToken: token.accessToken.jwtToken, idToken:token.idToken.jwtToken, refreshToken: token.refreshToken.token}
token = {accessToken, idToken, refreshToken}
dispatch({
type: 'TOKEN_SUCCESS',
data: token,
})}
).catch(error => {
dispatch({
type: 'TOKEN_ERROR',
error,
})
})
}
}
5.reducers.js
After the Store receives the Action, it must give a new State so that the View will change. This State calculation process is called Reducer.
A Reducer is a function that takes an Action and the current State as parameters and returns a new State.
import { combineReducers } from 'redux'
// 默认值
import defaultState from './state.js'
// 一个reducer就是一个函数
function areaIndex (state = defaultState.areaIndex, action) {
// 不同的action有不同的处理逻辑
switch (action.type) {
case 'SET_AREA_INDEX':
return action.data
default:
return state
}
}
function token (state = defaultState.token, action) {
console.log(action)
switch (action.type) {
case 'TOKEN_SUCCESS':
return action.data
default:
return state
}
}
// 导出所有reducer
export default combineReducers({
areaIndex,
token
})
6. Use state in LoginPage component
import { connect } from 'react-redux'
import { loadToken, setAreaIndex } from './store/actions.js'
class LoginPage extends Component {
state = {
username: '',
password: '',
}
loginAbroad = () => {
const { setToken, setAreaIndex } = this.props
setToken(this.state.username,this.state.password)
}
......
}
//将state映射到组件的props中
const mapStateToProps = (state) => {
return {
token: state.token,
areaIndex: state.areaIndex
}
}
//将dispatch映射到组件的props中
const mapDispatchToProps = (dispatch, ownProps) => {
return {
setToken: (username,password) => {
dispatch(loadToken(username,password))
},
setAreaIndex: (data) => {
dispatch(setAreaIndex(data))
}
}
}
//React-Redux 提供connect方法,用于从 UI 组件生成容器组件。connect的意思,就是将这两种组件连起来。
export default connect(mapStateToProps, mapDispatchToProps)(LoginPage)