1.安装相关依赖
npm add redux react-redux @types/react-redux redux-devtools-extension
2.在src目下新建项目建构:
3.store代码如下
store入口文件 /store/index.ts
import { applyMiddleware, createStore } from "redux";
import { composeWithDevTools } from "redux-devtools-extension"; /* 使用redux调试工具 */
import reducers from "./reducers";
export type rootState = ReturnType<typeof reducers>;
const store = createStore(reducers, composeWithDevTools(applyMiddleware()));
export default store;
4.reducer入口文件 /store/reducers/index.ts
import { combineReducers } from "redux";
import user from "./user";
export default combineReducers({ user });
5.user模块reducer /store/reducers/user.ts
export interface IUser {
id: string;
name: string;
role: string;
}
export interface IUserState {
user: IUser;
}
const initUserState: IUserState = {
/* state默认值 */
user: {
id: "default",
name: "普通用户",
role: "user",
},
};
export enum IUserActionType {
/* Actions */
INIT,
CHANGE,
}
const user = (
state: IUserState = initUserState,
action: { type: IUserActionType; payload: any }
) => {
const { payload } = action;
switch (action.type) {
case IUserActionType.INIT:
return state;
case IUserActionType.CHANGE:
return { ...state, user: { ...state.user, ...payload } };
default:
return state;
}
};
export default user;
6.在项目入口文件index.tsx内引入红框里的内容
-
在组件中使用
里
下面所有@引用的路径没有配置@用不了,会报错
自己找一下路径,例如./../store
1.在类组件中使用
/* 类组件使用redux */ import React, { Component } from 'react' import { connect } from 'react-redux' import { Dispatch } from 'redux' import { rootState } from '@/store' import { IUser, IUserActionType } from '@/store/reducers/user' interface IProps { user: IUser changeName?: (name: string) => void } class ClassComp extends Component<IProps> { protected handleChangeName(name: string) { this.props.changeName && this.props.changeName(name) } render() { const { name } = this.props.user return ( <div> {name} <br /> <button onClick={() => { this.handleChangeName("张三") }}>ClassComp改变名字</button> </div> ) } } const mapStateToProps = (state: rootState) => { return { ...state.user } } const mapDispatchToProps = (dispatch: Dispatch) => ({ changeName: (name: string) => { dispatch({ type: IUserActionType.CHANGE, payload: { name } }) } }) export default connect(mapStateToProps, mapDispatchToProps)(ClassComp)
2.在函数式组件中使用
/* 函数式组件使用redux */ import React from 'react' import { connect } from 'react-redux' import { Dispatch } from 'redux' import { rootState } from '@/store' import { IUser, IUserActionType } from '@/store/reducers/user' interface IProps { user: IUser changeName?: (name: string) => void } function FnComp(props: IProps) { const { user: { name }, changeName } = props const handleChangeName = (name: string) => { changeName && changeName(name) } return ( <div> {name} <br /> <button onClick={() => { handleChangeName("李四") }}>FnComp改变名字</button> </div> ) } const mapStateToProps = (state: rootState) => { return { ...state.user } } const mapDispatchToProps = (dispatch: Dispatch) => ({ changeName: (name: string) => { dispatch({ type: IUserActionType.CHANGE, payload: { name } }) } }) export default connect(mapStateToProps, mapDispatchToProps)(FnComp)
3.配合Hook使用
/* Hook使用redux */ import React from 'react' import { useDispatch, useSelector } from 'react-redux' import { rootState } from '@/store/index' import { IUserState, IUserActionType } from '@/store/reducers/user' export default function HookComp() { const { user } = useSelector<rootState, IUserState>((state) => state.user) const dispatch = useDispatch() const handleChangeName = (name: string) => { dispatch({ type: IUserActionType.CHANGE, payload: { name } }) } return ( <div> {user.name} <br /> <button onClick={() => { handleChangeName("王五") }}>HookComp改变名字</button> </div> ) }