store
数据封装
- 新建目录:
src/redux
、src/redux/language
- 新建文件:
src/redux/store.ts
、src/redux/language/actionCreators.ts
,src/redux/language/reducers.ts
mkdir src/redux src/redux/language
touch src/redux/language/actionCreators.ts src/redux/language/reducer.ts
touch src/redux/product/actions.ts src/redux/product/reducer.ts
import { createStore, combineReducers, applyMiddleware } from 'redux'
import languageReducer form './language/reducer.ts'
import productReducer form './product/reducer.ts'
import thunk form 'redux-thunk'
// 使用 combineReducers方法,连接多个reducer
const rootReducer = combineReducers({
language: languageReducer,
product: productReducer
})
// redux-thunk 使用thunk中间件,使得redux的action除了对象形式,还是支持函数类型
const store = createStore(rootReducer, applyMiddleware(thunk))
// 使用ts的条件类型 ReturnType<T>,T:函数类型。 获取函数返回值的类型
export type RootState = ReturnType<typeof store.getState>
export default store
- product:-
product/actions.ts
、product/reducers.ts
actions.ts
// 使用redux-thunk,支持函数类型的action,这个action的类型:ThunkAction<R,S,E,A>
import { ThunkAction } from 'react-thunk'
import axios from 'axios'
import { RootState } from 'redux/store'
// fetch_start 主要是用来控制loading, 开始发接口,loading值为true
export const FETCH_START = 'product/fetch_start'
// fetch_success 主要用来 接口数据成功,将数据data存入store
export const FETCH_SUCCESS = 'product/fetch_success'
export const FETCH_FAIL = 'product/fetch_fail'
interface ActionFetchStartProps { type: typeof FETCH_START}
interface ActionFetchSuccessProps { type: typeof FETCH_SUCCESS, payload: any}
interface ActionFetchFailProps { type: typeof FETCH_FAIL }
export type ActionsProductProps = ActionFetchStartProps | ActionFetchSuccessProps | ActionFetchFailProps
// actionCreator
export const fetchStartActionCreator = (): ActionFetchStartProps => ({ type: FETCH_START})
export const fetchSuccessActionCreator = (data:any):ActionFetchSuccessProps => ({ type: FETCH_SUCCESS, payload: data })
export const fetchFailActionCreator = ():ActionFetchFailProps => ({ type: FETCH_FAIL })
// 函数类型的action
export const fetchProductsActionCreator = (): ThunkAction<void, RootState, unknown, ActionsProductProps>=> async (dispatch, getState) => {
dispactch(fetchStartActionCreator())
try{
const { data } = await axios.get('/api/products')
dispatch(fetchSuccessActionCreator(data))
}catch{
dispatch(fetchFailActionCreator())
}
}
reducer.ts
import { ActionsProductProps, FETCH_START, FETCH_SUCCESS, FETCH_FAIL } from './actions.ts'
interface ProductState {
loading: boolean,
productList: any[]
}
const defaultState: ProductState = {
loading: false,
productList: []
}
export default (state = defaultState, action:ActionsProductProps ) => {
switch (action.type) {
case FETCH_START:
return { ...state, loading: true }
case FETCH_SUCCESS:
return { ...state, loading: false, tourists: action.payload }
case FETCH_FAIL:
return { ...state, loading: false }
default:
return state
}
}
- language:-
language/actions.ts
、language/reducers.ts
actions.ts
/* 用常量定义action.type,减少代码敲错 */
export const ADD_LANGUAGE = 'language/add'
export const CHANGE_LANGUAGE = 'language/change'
/* action的类型申明 */
const AddActionProps = {
type: typeof ADD_LANGUAGE,
payload: { code: string, language: string }
}
const ChangeActionProps = {
type: typeof CHANGE_LANGUAGE,
payload: 'zh' | 'en'
}
export type LanguageActionProps = AddActionProps | ChangeActionProps
/* 用工厂模式创建action */
export const addLanguageActionCreator = (language: {code: string, language: string}):ADD_LANGUAGE => {
return {
type: ADD_LANGUAGE,
payload: language
}
}
export const changeLanguageActionCreator = (lng: 'zh' | 'en'):CHANGE_LANGUAGE => {
return {
type: CHANGE_LANGUAGE,
payload: lng
}
}
2. `reducer.ts`
import { ADD_LANGUAGE, CHANGE_LANGUAGE, LanguageActionProps } from './actions'
export interface LanguageState {
lng: 'zh' | 'en',
languageList: {code: string, language: string}[]
}
const defaultStoreState: LanguageState = {
lng: 'zh',
languageList: [{ code: 'zh', language: '中文'}, { code: 'en', language: 'English'}]
}
export default (state = defaultStoreState, action:LanguageActionProps) => {
switch (action.type) {
case CHANGE_LANGUAGE:
return { ...state, lng: action.payload }
case ADD_LANGUAGE:
return { ...state, languageList: [...state.languageList, action.payload] }
default:
return state
}
}