React 在 TS 中使用 Redux
- 这里我选择了使用 react-redux,redux-thunk,redux 
- 除了上面这 3 个还需要在安装一个 
(1)安装包依赖
cnpm install @types/react-redux
cnpm i redux
cnpm i react-redux
cnpm i redux-thunk
(2) (特别重要) 修改 react-app-env.d.ts
- 在 src 目录下面有一个文件 react-app-env.d.ts
修改这个文件的代码
/// <reference types="react-scripts" />
// 修改ReduxTools工具
interface Window extends REDUXTOOS {
  __REDUX_DEVTOOLS_EXTENSION_COMPOSE__:
    | string
    | __REDUX_DEVTOOLS_EXTENSION_COMPOSE__;
}
declare var window: Window(3) 在 src 目录下新建一个 store 文件夹,然后接着创建下面几个文件
- actiontypes.tsx 
- actioncreaters.tsx 
- reducers.tsx 
- store.tsx 
(i) actiontype.tsx
- 规定 action 的名字
export const ADD = 'ADD'
export const DELETE = 'DELETE'
export const CHANGE_VALUE = 'CHANGE_VALUE'(ii) actioncreaters.tsx
- 创建 action
引入名字 然后定义返回值类型,最后暴露出去方法和方法类型,方法类型这里因为一样所以我用了或写法 也可以拆分
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,
  }
}
(iii) reducers.tsx
- 写获取到数据后的处理方法 
- 定义数据类型(也可以暴露出去) 
- 绑定 action 数据类型 
- 最后暴露类型 
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
  }
}
(iiii) store.tsx
- 因为用了第二步所以他不会报错误
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(4) 组件里面使用
- 必须继承 RouteComponentProps 否则一定会报错
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))
(5) index.tsx 里面代码 引入 store
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')
) 
                        
                        