react-typescript新项目使用redux,并结合redux-thunk,redux-devtools-extension

typescript版的redux(结合hooks)使用

1.安装redux全家桶
这里需要注意react-redux的版本以及redux-thunk的版本,不然会出现什么类型不对,或者无提示的bug

npm i redux @types/redux redux-devtools-extension

npm i redux-thunk@2.3.0

npm i react-redux@7

文件目录如下
在这里插入图片描述

store/index.ts文件内容

import { applyMiddleware, legacy_createStore } from 'redux'
import { composeWithDevTools } from 'redux-devtools-extension'
import thunk, { ThunkAction } from 'redux-thunk'
import RootReducer from './reducers'
import { todoAction } from './actions/todos'
const middleWare = [thunk]
const store = legacy_createStore(
  RootReducer,
  composeWithDevTools(applyMiddleware(...middleWare))
)
// 后续有多个action的话直接用联合类型运算符| 如=》todoAction | myAction
export type RootAction = todoAction
// ReturnType返回state的类型
// 导出这个供给useSelector使用,见官网链接 https://redux.js.org/usage/usage-with-typescript#typing-the-useselector-hook
export type RootState = ReturnType<typeof store.getState>
export type AppDispatch = typeof store.dispatch
// 主要是给异步action使用,返回值的类型需要这个
// 见文档https://redux.js.org/usage/usage-with-typescript#type-checking-redux-thunks
export type RootThunkAction = ThunkAction<void, RootState, unknown, RootAction>
export default store

store/reducers/index.ts内容

import { combineReducers } from "redux";
import todos from './todos'
export default combineReducers({
    todos
})

store/reducers/todo.ts内容

import { todoAction } from '../actions/todos'

export type TodosType = {
  id: number
  name: string
  done: boolean
}[]
const initValue: TodosType = []
export default function todos (state = initValue, action: todoAction) {
  switch (action.type) {
    case 'todo/gettodos': {
      return action.payload
    }
    default: {
      return state
    }
  }
}

store/actions/todos.ts内容

import { RootThunkAction } from '..'
import { TodosType } from '../reducers/todos'

export type todoAction = {
  type: 'todo/gettodos'
  payload: TodosType
}
// 固定返回值,需要是RootThunkAction
export const getTodos = (): RootThunkAction => {
  return async dispatch => {
    // 这里模拟axios请求,所以res直接给any了
    const res:any = await new Promise(resolve=>{
        setTimeout(() => {
            return resolve({"data":{"channels":[{"id":0,"name":"推荐"},{"id":1,"name":"html"},{"id":2,"name":"开发者资讯"},{"id":4,"name":"c++"},{"id":6,"name":"css"},{"id":7,"name":"数据库"},{"id":8,"name":"区块链"},{"id":9,"name":"go"},{"id":10,"name":"产品"},{"id":11,"name":"后端"},{"id":12,"name":"linux"},{"id":13,"name":"人工智能"},{"id":14,"name":"php"},{"id":15,"name":"javascript"},{"id":16,"name":"架构"},{"id":17,"name":"前端"},{"id":18,"name":"python"},{"id":19,"name":"java"},{"id":20,"name":"算法"},{"id":21,"name":"面试"},{"id":22,"name":"科技动态"},{"id":23,"name":"js"},{"id":24,"name":"设计"},{"id":25,"name":"数码产品"},{"id":26,"name":"软件测试"}]},"message":"OK"})
        }, 200);
    })
    
    dispatch({
      type: 'todo/gettodos',
      payload: res.data.channels
    })
  }
}


App.tsx文件:

import { useEffect } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { RootState } from './store'
import { getTodos } from './store/actions/todos'
function App () {
  const state = useSelector((state: RootState) => state.todos)
  const dispatch = useDispatch()
  useEffect(() => {
    dispatch(getTodos())
  }, [])
  return (
    <div className='App'>
      <ul>
        {state.map(item => (
          <li key={item.id}>{item.name}</li>
        ))}
      </ul>
    </div>
  )
}

export default App

最后,别忘了main.tsx中,把store挂载上去

import ReactDOM from 'react-dom'
import { Provider } from 'react-redux'
import App from './App'
import store from './store'
ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
)

此时页面加载就会自动调用dispatch发起请求获取数据,然后存到redux,控制台的redux插件可以看

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值