美文网首页
react-redux-typescript

react-redux-typescript

作者: Xludan | 来源:发表于2019-08-15 17:24 被阅读0次

    react redux Typescript 的使用

    新建项目

    用create-react-app新建一个react项目

    create-react-app xxx --typescript
    

    安装依赖

    安装redux

    yarn add redux @types/redux react-redux @types/react-redux;
    

    或者

    npm install redux @types/redux react-redux @types/react-redux;
    

    创建store

    import { createStore, combineReducers, applyMiddleware } from 'redux';
    import thunkMiddleware from 'redux-thunk';
    import { composeWithDevTools } from 'redux-devtools-extension';
    
    import { systemReducer } from './system/reducers';
    import { chatReducer } from './chat/reducers';
    
    const rootReducer = combineReducers({
      system: systemReducer,
      chat: chatReducer
    });
    
    export type AppState = ReturnType<typeof rootReducer>;
    
    export default function configureStore() {
      const middlewares = [thunkMiddleware];
      // applyMiddleware引入中间件
      const middleWareEnhancer = applyMiddleware(...middlewares);
    
      const store = createStore(
        rootReducer,
        composeWithDevTools(middleWareEnhancer)
      );
    
      return store;
    }
    

    引用store

    import * as React from 'react';
    import { render } from 'react-dom';
    import { Provider } from 'react-redux';
    import configureStore from './store';
    
    import App from './App';
    
    const store = configureStore();
    
    const Root = () => (
      <Provider store={store}>
        <App />
      </Provider>
    );
    
    render(<Root />, document.getElementById('root'));
    

    编写组件

    typescript的写法就是在class前加上props 和 state的类型,比如:

    import React from 'react';
    
    interface IProps{}
    interface IState{
      xx: string;
      yy: number
    }
    
    class MyComponent extends React.Component<Props, State> {
      constructor(props: IProps) {
        super(props);
        this.state={
          xx: '',
          yy: 1
        }  
      }
    
      render(){
        return (
          <>
          ...
          </>
        )
      }
    }
    

    实例

    一个简单的聊天应用程序来演示包含静态类型的可能方法。这个聊天应用程序将有两个 reducer。chat reducer 将专注于存储聊天记录,system reducer 将专注于存储会话信息。

    为 State 增加类型检查

    向每个 state 切片添加类型是一个很好的开始,因为它不依赖于其他类型。在这个例子中,我们首先描述 chat reducer 相关的 state 切片:

    // src/store/chat/types.ts
    
    export interface Message {
      user: string
      message: string
      timestamp: number
    }
    
    export interface ChatState {
      messages: Message[]
    }
    

    然后对 system reducer 相关的 state 切片做同样的处理:

    // src/store/system/types.ts
    
    export interface SystemState {
      loggedIn: boolean
      session: string
      userName: string
    }
    

    导出的这些 interface,稍后在 reducer 和 action creators 中都能重用它们。

    为 Action & Action Creator 增加类型检查

    chat Action 常量和形状:

    // src/store/chat/types.ts
    export const SEND_MESSAGE = 'SEND_MESSAGE'
    export const DELETE_MESSAGE = 'DELETE_MESSAGE'
    
    interface SendMessageAction {
      type: typeof SEND_MESSAGE
      payload: Message
    }
    
    interface DeleteMessageAction {
      type: typeof DELETE_MESSAGE
      meta: {
        timestamp: number
      }
    }
    
    export type ChatActionTypes = SendMessageAction | DeleteMessageAction
    

    此处使用 TypeScript 的联合类型来表达所有可能的操作。

    声明这些类型后,我们现在还可以对 chat 的 action creator 做类型检查。在这种情况下,我们利用 TypeScript 的 inference:

    // src/store/chat/actions.ts
    
    import { Message, SEND_MESSAGE, DELETE_MESSAGE } from './types'
    
    // TypeScript infers that this function is returning SendMessageAction
    export function sendMessage(newMessage: Message) {
      return {
        type: SEND_MESSAGE,
        payload: newMessage
      }
    }
    
    // TypeScript infers that this function is returning DeleteMessageAction
    export function deleteMessage(timestamp: number) {
      return {
        type: DELETE_MESSAGE,
        meta: {
          timestamp
        }
      }
    }
    

    system action 常量和形状:

    // src/store/system/types.ts
    export const UPDATE_SESSION = 'UPDATE_SESSION'
    
    interface UpdateSessionAction {
      type: typeof UPDATE_SESSION
      payload: SystemState
    }
    
    export type SystemActionTypes = UpdateSessionAction
    

    有了这些类型,现在也可以对 system 的 action creator 做类型检查:

    // src/store/system/actions.ts
    
    import { SystemState, UPDATE_SESSION } from './types'
    
    export function updateSession(newSession: SystemState) {
      return {
        type: UPDATE_SESSION,
        payload: newSession
      }
    }
    

    为 reducer 增加类型检查

    reducer 只是纯函数,它输入 先前的 state 和一个 action 然后返回下一个 state。在此示例中,我们显式声明此 reducer 将接收的 action 类型以及它应返回的内容(适当的 state 切片)。 通过这些添加,TypeScript 将在我们的 action 和 state 的属性上提供丰富的智能感知。

    // src/store/chat/reducers.ts
    
    import {
      ChatState,
      ChatActions,
      ChatActionTypes,
      SEND_MESSAGE,
      DELETE_MESSAGE
    } from './types'
    
    const initialState: ChatState = {
      messages: []
    }
    
    export function chatReducer(
      state = initialState,
      action: ChatActionTypes
    ): ChatState {
      switch (action.type) {
        case SEND_MESSAGE:
          return {
            messages: [...state.messages, action.payload]
          }
        case DELETE_MESSAGE:
          return {
            messages: state.messages.filter(
              message => message.timestamp !== action.meta.timestamp
            )
          }
        default:
          return state
      }
    }
    

    已增加类型检查的 system reducer:

    // src/store/system/reducers.ts
    
    import {
      SystemActions,
      SystemState,
      SystemActionTypes,
      UPDATE_SESSION
    } from './types'
    
    const initialState: SystemState = {
      loggedIn: false,
      session: '',
      userName: ''
    }
    
    export function systemReducer(
      state = initialState,
      action: SystemActionTypes
    ): SystemState {
      switch (action.type) {
        case UPDATE_SESSION: {
          return {
            ...state,
            ...action.payload
          }
        }
        default:
          return state
      }
    }
    

    生成 root reducer 函数,通常使用 combineReducers 来完成。请注意,我们不必为 AppState 显式声明新接口。 我们可以使用 ReturnType 从 rootReducer 推断状态形状。

    // src/store/index.ts
    
    import { systemReducer } from './system/reducers'
    import { chatReducer } from './chat/reducers'
    
    const rootReducer = combineReducers({
      system: systemReducer,
      chat: chatReducer
    })
    
    export type AppState = ReturnType<typeof rootReducer>
    

    对 mapStateToProps 接收的参数添加类型检查,将 action creator 映射到组件的 props 中

    // src/App.tsx
    import React, {Component} from 'react'
    import {connect} from 'react-redux'
    import { AppState } from './store'
    
    import { SystemState } from './store/system/types'
    import { updateSession } from './store/system/actions'
    
    import { ChatState } from './store/chat/types'
    import { sendMessage } from './store/chat/actions'
    
    interface AppProps {
      chat: ChatState
      system: SystemState
      sendMessage: typeof sendMessage
      updateSession: typeof updateSession
    }
    
    class App extends Component<AppProps>{
    
    }
    
    const mapStateToProps = (state: AppState) => (
      // 此处的类型将在AppProps处校验
      {
        system: state.system,
        chat: state.chat
      }
    )
    
    export default connect(mapStateToProps, { updateSession,sendMessage })(App)
    

    相关文章

      网友评论

          本文标题:react-redux-typescript

          本文链接:https://www.haomeiwen.com/subject/jwxodctx.html