redux的使用

1.安装

yarn add react-thunk
yarn add redux-promise
yarn add redux
yarn add react-redux

项目目录

在这里插入图片描述

2.定义两个reduce

count.ts

type InitStore = {
  num: number
}
export type CountAction = {
  type: string,
  num: number
}

// store初始值
const initStore: InitStore = { num: 100 };

// 创建各个操作
第一个参数为初始值,第二个参数为操作
export const countReducer = (state = initStore, action: CountAction) => {
  switch (action.type) {
    case 'Add':
      return {
        ...state,
        num: state.num += action.num
      };
    case 'Decrement':
      return {
        ...state,
        num: state.num -= action.num
      };
    case 'Multi':
      return {
        ...state,
        num: state.num *= action.num
      };
    case 'Division':
      return {
        ...state,
        num: state.num /= action.num
      };
    default:
      return state;
  }
};

user.ts

type InitStore = {
  user: string
  isLogin: boolean
  text: string
}
type UserAction = {
  type: string,
  isLogin: boolean,
  text: string
}

// store初始值
const initStore: InitStore = {
  user: 'admin',
  isLogin: false,
  text: '未登录'
};

// 创建各个操作
export const userReducer = (state = initStore, action: UserAction) => {
  switch (action.type) {
    case 'Login':
      return {
        ...state,
        isLogin: action.isLogin,
        text: action.text
      };
    case 'Logout':
      return {
        ...state,
        isLogin: action.isLogin,
        text: action.text
      };
    default:
      return state;
  }
};

3.定义所有的action

action.ts

const increment = {
  type: 'Add',
  num: 1
};
const decrement = {
  type: 'Decrement',
  num: 1
};
const multi = {
  type: 'Multi',
  num: 2
};
const division ={
  type: 'Division',
  num: 2
};
const login = {
  type: 'Login',
  isLogin: true,
  text: '已登录'
};
const logout = {
  type: 'Logout',
  isLogin: false,
  text: '未登录'
};

export {
  increment,decrement,multi,division,login,logout
};

4.创建store

index.ts

import { createStore, combineReducers } from 'redux';
import { countReducer } from './count';
import { userReducer } from './user';

const reducer = combineReducers({
  user: userReducer,
  count: countReducer
});

export function userStore() {
  return createStore(reducer);
}

5. store.subscribe()函数的使用

store.subscribe()监听store数据的变化,只要数据发生变化那么这个函数就会执行

6.store与组件关联实现数据修改后刷新页面

  • 将store传递给子代
index.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import 'nprogress/nprogress.css';
import './style/index.css';
import {
  BrowserRouter as Router,
} from 'react-router-dom';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { userStore } from './store';
import { Provider } from 'react-redux';

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement,
);
root.render(
  <Router>
    <Provider store={userStore()}>  //将store传递给子代
      <App/>
    </Provider>
  </Router>
);

reportWebVitals();
  • 子代获取store里面的操作
    mapStateToProps
    mapDispatchToProps
    connect(mapStateToProps, mapDispatchToProps)(componentName)
//Test.tsx
import React, { useEffect } from 'react';
import { connect, MapStateToProps } from 'react-redux';
import { RootStore, userStore } from '../store';
import { login, decrement, increment, logout } from '../store/actions';
import { Dispatch } from 'redux';

type Props = {
  store: RootStore
  addN: (value: number) => { type: string, num: number }
}

const Test: React.FC<Props> = (props) => {
  const { store, addN} = props;
  return (
    <>
      <div>test</div>
      <div>{store.count.num}</div>
      <button onClick={()=>addN(50)}>+1</button>
    </>
  );
};



const mapStateToProps:MapStateToProps<any, any, any> = (state: RootStore) => {
  return {
    store:state
  };
};
const mapDispatchToProps = (dispatch: Dispatch) => {
  return {
    addN: (value: number) => dispatch(increment(value)),
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(Test);

7.处理异步任务

引入中间件

import { createStore, combineReducers,applyMiddleware } from 'redux';
import { countReducer, InitCountStore } from './count';
import { InitUserStore, userReducer } from './user';
import thunk from 'redux-thunk'

export type RootStore= {
  user:InitUserStore
  count:InitCountStore
}

const reducer = combineReducers({
  user: userReducer,
  count: countReducer
});

export function userStore() {
  return createStore(reducer,applyMiddleware(thunk));    //使用异步中间件
}

定义一个异步任务

const fuck = () => {
  return new Promise((resolve, reject) => {
    // axios.get<number>('/xxx')
    //   .then(res => {
    //     resolve({
    //       type: 'Reset',
    //       num: res
    //     });
    //   });
    setTimeout(() => {
      resolve({
        type: 'Add',       
        num: 900
      });
    },3000);
  });
};


将异步任务操作传给组件

const mapDispatchToProps =  (dispatch: Dispatch) => {
  return {
    addN: (value: number) => dispatch(increment(value)),
    subN: (value: number) => dispatch(decrement(value)),
    signin:()=>dispatch(login),
    signout:()=>dispatch(logout),
    resetN:async ()=>dispatch((await fuck()) as AnyAction)  //异步任务映射到props
  };
};

组件调用

const Test: React.FC<Props> = (props) => {
  const { store, addN,signin,signout,resetN} = props;
  return (
    <>
      <div>test</div>
      <div>{store.count.num}</div>
      <div>{JSON.stringify(store.user)}</div>
      <button onClick={()=>addN(50)}>+1</button>
      <button onClick={()=>signin()}>+login</button>
      <button onClick={()=>signout()}>+login</button>
      <button onClick={()=>resetN()}>重置</button>    //调用异步任务
    </>
  );
};

注意

另外redux的书写很麻烦官方推荐使用 @reduxjs/toolkit这个库

源码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值