Skip to content

React 在 TS 中使用 Redux

  • 这里我选择了 react-redux ,redux-thunk,redux

安装包依赖

javascript
cnpm install @types/react-redux
cnpm i redux
cnpm i react-redux
cnpm i redux-thunk

(特别重要) 修改 react-app-end.d.ts

  • 在 src 目录下面有一个文件 react-app-env.d.ts
javascript
/// <reference types="react-scripts" />
// 修改ReduxTools工具
interface Window extends REDUXTOOS {
  __REDUX_DEVTOOLS_EXTENSION_COMPOSE__:
    | string
    | __REDUX_DEVTOOLS_EXTENSION_COMPOSE__;
}

declare var window: Window;

在 src 目录下新建一个 store 文件夹,接着创建下面几个文件

  • actiontypes.tsx

  • actioncreaters.tsx

  • reducers.tsx

  • store.tsx

actiontype.tsx

  • 规定 action 的名字
javascript
export const ADD = "ADD";
export const DELETE = "DELETE";
export const CHANGE_VALUE = "CHANGE_VALUE";

actioncreaters.tsx

  • 创建数据处理工厂
javascript
import { ADD, DELETE, CHANGE_VALUE } from './actiontypes'
//定义返回类型
interface ADD_RESULT {
  type: string
}
interface DELETE_RESULT {
  type: string
  value: number
}

interface CHANGE_VALUE_RESULT {
  type: string
  value: string
}

//定义方法

export const add_action = (): ADD_RESULT => {
  return {
    type: ADD,
  }
}

export const delete_action = (value: number): DELETE_RESULT => {
  return {
    type: DELETE,
    value: value,
  }
}

export const change_action = (value: string): CHANGE_VALUE_RESULT => {
  return {
    type: CHANGE_VALUE,
    value: value,
  }
}

reducers.tsx

  • 写获取到数据后的处理方法

  • 定义数据类型

  • 绑定 action 数据类型

  • 最后暴露类型

javascript
import { ADD, DELETE, CHANGE_VALUE } from './actiontypes'

//定义数据

export interface StateResult {
  value: string
  list: (string | number)[]
}

const defaultResult: StateResult = {
  value: '',
  list: [],
}

export default (state = defaultResult, action: any): StateResult => {
  switch (action.type) {
    case ADD:
      let newresult = JSON.parse(JSON.stringify(state))
      newresult.list.push(state.value)
      newresult.value = ''
      return newresult
    case DELETE:
      let newresult2 = JSON.parse(JSON.stringify(state))
      newresult2.list.splice(action.value, 1)
      return newresult2
    case CHANGE_VALUE:
      let newresult3 = JSON.parse(JSON.stringify(state))
      newresult3.value = action.value
      return newresult3
    default:
      return state
  }
}

store.tsx

  • 改变 store 里面的内容
javascript
import { createStore, compose, applyMiddleware } from "redux";
import reducer from "./reducers";
import thunk from "redux-thunk";

const composeEnhancers =
  typeof window === "object" && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
    ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
        // Specify extension’s options like name, actionsBlacklist, actionsCreators, serialize...
      })
    : compose;

const enhancer = composeEnhancers(applyMiddleware(thunk));

const store = createStore(reducer, enhancer);

export default store;

组件里面使用

  • 必须继承 RouteComponentProps 否则一定会报错
javascript

import * as React from 'react'
import { withRouter, Link, RouteComponentProps } from 'react-router-dom'
import { connect } from 'react-redux'
import { StateResult } from '../../store/reducers'
import {
  add_action,
  delete_action,
  change_action,
} from '../../store/actioncreaters'
interface IHomeProps extends RouteComponentProps {
  value: string
  list: (string | number)[]
  handleAdd: () => void
  handleDel: (value: number) => void
  handleChange: (value: any) => void
}

const Home: React.FunctionComponent<IHomeProps> = (props) => {
  const { value, list, handleAdd, handleChange, handleDel } = props
  return (
    <div>
      <span>这就是首页 </span>
      <input type="text" onChange={handleChange} value={value}></input>
      <button onClick={handleAdd}>增加</button>
      <ul>
        {list.map((item, index) => {
          return (
            <li
              key={index}
              onClick={() => {
                handleDel(index)
              }}
            >
              {' '}
              {item}
            </li>
          )
        })}
      </ul>
      <Link to="/second">点击跳转</Link>
    </div>
  )
}
const mapStateToProps = (state: StateResult) => {
  return {
    value: state.value,
    list: state.list,
  }
}

const mapDispatchToProps = (dispatch: any) => {
  return {
    handleAdd() {
      dispatch(add_action())
    },
    handleDel(value: number) {
      dispatch(delete_action(value))
    },
    handleChange(e: any) {
      let result = e.target.value
      dispatch(change_action(result))
    },
  }
}
export default connect(mapStateToProps, mapDispatchToProps)(withRouter(Home))

index.tsx 里面代码引入 store

javascript
import React from "react";
import ReactDOM from "react-dom";
import "./reset.css";
import RouterComponent from "./router";
import { Provider } from "react-redux";
import store from "./store/store";
ReactDOM.render(
  <Provider store={store}>
    <RouterComponent />
  </Provider>,

  document.getElementById("root")
);