从0~1配置 redux TypeScript 版
一、redux 相关配置
1、安装 redux 相关的包
yarn add redux react-redux redux-thunk@2.3.0 redux-devtools-extension axios
redux-thunk@2.3.0
中间件指定版本因为这个版本是有提示的,书写更方便
2、在 store 目录中分别创建:actions 和 reducers 文件夹、index.ts 文件
store 目录结构:
/store
/actions
/reducers
index.ts
index.ts
3、在 store/index.ts 中,创建 store 并导出
import { createStore,applyMiddleware } from "redux";
import thunk from "redux-thunk";
import { composeWithDevTools } from "redux-devtools-extension";
import rootReducer from './reducers'
const middlewares = composeWithDevTools(applyMiddleware(thunk))
const store = createStore(rootReducer,middlewares)
export default store
4、创建 reducers/index.ts 文件,创建 rootReducer 并导出
假如目前已经写了一个 login 登陆的 reducers 导入 根 rootReducer 里面并且导出
import { combineReducers } from "redux";
import {login} from './login'
const rootReducer = combineReducers({
login
})
export default rootReducer
5、配置login(登陆)的 action
登陆 action 需要走异步,所以我们 return dispatch 派发的是一个函数,
如果是同步则派发的是一个对象
import { RootThunkAction } from '@/types/store'
import { http } from "@/utils/http";
import type { Token } from '@/types/data';
import { setToken } from '@/utils/token';
// login 函数的参数类型
type LoginParams = { mobile: string; code: string }
// login 接口的响应类型
type LoginResponse = {
message: string
data: Token
}
export const login = (data:LoginParams):RootThunkAction => {
return async dispatch => {
const res = await http.post<LoginResponse>('/authorizations',data)
// 拿到返回数据
const tokens = res.data.data
// // 设置本地token
setToken(tokens)
// 分发 action 将 token 保存到 redux state 中
dispatch({ type: 'login/token', payload: tokens })
}
}
6、创建 reducers/login.ts 文件,创建基础 login reducer 并导出
提前在 type 文件里面定义 store 的类型 和接口数据类型,这里采用了 token 跟 refresh_token 两个,提高用户体验
import type { Token } from "@/types/data"
import type { LoginAction } from "@/types/store"
const initialState: Token = {
token: '',
refresh_token: ''
}
export const login = (state = initialState, action: LoginAction): Token => {
switch (action.type) {
case 'login/token':
return action.payload
default:
return state
}
}
7、在 src/index.tsx 中为 React 组件接入 Redux
最后一步也是最重要的,别忘记在 index.tsx 文件导入 Provider 跟 store 将 App 组件包裹起来,
提供 store={我们的store}
import ReactDOM from 'react-dom'
import { Provider } from 'react-redux'
import App from './App'
import store from './store'
import './index.scss'
import 'lib-flexible'
ReactDOM.render(<Provider store={store}><App /></Provider>, document.querySelector('#root'))
二、配置Redux的相关类型、
1、在 types 目录中创建两个类型声明文件:store.d.ts
和 data.d.ts
types/store.d.ts 中我们配置的是 store 里面的类型,这里做的是一个移动端项目
import { ThunkAction } from "redux-thunk";
import store from '@/store'
import { Token } from "./data";
// Redux 应用的状态
// 使用 thunk 中间件后的 Redux dispatch 类型
// ReturnType:thunk action 的返回类型
// State: Redux 的状态 RootState
// ExtraThunkArg: 额外的参数,没有用到,可以指定为 unknown
// BasicAction: 非 thunk action,即对象形式的 action
export type RootState = ReturnType<typeof store.getState>
export type RootThunkAction = ThunkAction<void,
RootState,
unknown,
RootAction>
// 项目中所有 action 的类型
type RootAction = LoginAction
// 登录 action 类型
export type LoginAction = {
type: 'login/token'
payload: Token
}
// -------------------- Redux 对象形式的 action 的类型 ---------------------------
// 登录相关的 action 类型
// 文章相关的 action 类型
// 等等
types/data.d.ts 中我们配置的是 接口返回的数据类型,刚做登陆,就配置了 token 跟 refresh_token
// ---- 接口数据的所有类型
// 登录接口返回数据类型
export type Token = {
token: string
refresh_token: string
}
2、最终我们在组件派发 action 就行啦,这里也是最简单的
3、最后请看 redux 存储的 token 与 refresh_token,这里接口规定给 token 与 refresh_token,如果只给 token 去掉 refresh_token即可
点击登录按钮之后的 redux