美文网首页
redux在项目中使用

redux在项目中使用

作者: 咕嘟咕嘟li | 来源:发表于2021-06-12 17:47 被阅读0次

    页面截图:


    截图1 截图2

    src下目录如下

    src
    ├─actions
    │  └─choose-question.tsx
    ├─assets
    │  └─images
    ├─components
    ├─reducer
    │   └─actionTypes.tsx
    │   └─choose-question.tsx
    │   └─index.tsx
    │   └─store.tsx
    ├─router
    ├─css
    ├─views
    │   └─my-paper.tsx
    │   └─paper.tsx
    │   └─paper2.json // 题目数据
    ├─App.tsx
    └─index.tsx
    

    安装redux

    cnpm install --save redux react-redux @types/react-redux @types/redux

    • reducer 目录包含所有Redux的reducer
    • actions 目录包含所有action构造函数
    • components 目录包含所有的傻瓜组件
    • containers 目录包含所有的容器组件 (本项目暂时不用)

    Redux的3个基本原则:

    1. 唯一数据源
    2. 保持状态只读
    3. 数据改变只能通过纯函数完成

    reducer目录下新建一个store.tsx

    reducer目录下新建一个store.tsx(这个store.tsx文件也可以不用建,把里面的代码直接放到App组件中),代码如下

    import { createStore } from 'redux'
    import reducer from './index'
    
    // store 是一个必须包含3个函数 subscribe dispatch getState的对象
    let store = createStore(reducer)
    
    export default store
    

    Provider作为根组件提供上下文环境,保证store可以被所有组建访问到

    一个应用中,最好只有一个地方需要直接导入Store,这个位置当然应该是在调用最顶层React组件的位置,其余组件应该避免直接导入Store。

    该项目中在App.tsx中导入Store后,其余地方就没有再次导入了

    在App.tsx中导入Store

    App.tsx

    import React from 'react'
    // 提供包含store的context
    import { Provider } from 'react-redux'
    import store from './reducer/store'
    
    import ConfigRouter from './router/router' // 自己配置的路由模块
    import './App.css'
    export default class App extends React.Component {
      render () {
        return (
          <Provider store={store}>
            <ConfigRouter />
          </Provider>
        )
      }
    }
    

    选题模块reducer

    选题模块reducer(reducer/choose-question.tsx)如下:

    import { SELECTED_QUESTION, QUESTION_CATALOG} from './actionTypes'
    
    const initialState = {
      selectedQuestion: [], // 选中的题目
      questionCatalog: {} // 选中题目的id
    }
    
    export const getSelectedQuestion = (state:any) => state.selectedQuestion
    export const getQuestionCatalog = (state:any) => state.questionCatalog
    
    const chooseQuestion = (state = initialState, action: any) => {
      switch (action.type) {
        case SELECTED_QUESTION:
          return {
            selectedQuestion: [...action.payload],
            questionCatalog: getQuestionCatalog(state)
          }
    
        case QUESTION_CATALOG:
          return {
            questionCatalog: {...action.payload},
            selectedQuestion: getSelectedQuestion(state)
          }
        
        default:
          return {
            selectedQuestion: getSelectedQuestion(state),
            questionCatalog: getQuestionCatalog(state)
          }
      }
    }
    
    export default chooseQuestion
    

    combineReducers组合多个reducer

    因为考虑到会有多个模块的reducer,所以reducer/index.tsx文件里使用combineReducers组合reducer

    import { combineReducers } from 'redux'
    import chooseQuestion from './choose-question' // 选题模块的reducer
    
    // 组合reducer
    export default combineReducers({
      chooseQuestion
    })
    
    

    调用action里的方法去修改store里的状态

    组件内通过调用action里的方法(actions/choose-question.tsx)去修改store里的状态,action/choose-question.tsx文件定义修改store状态的方法之一如下:

    export const addQuestionCatalog = (question: object) => {
      return {
        type: QUESTION_CATALOG,
        payload: question
      }
    }
    

    需要用到状态管理的组件

    1. 引入connect

    connect方法接收两个参数mapStateToProps和mapDispatchToProps,执行结果依然是一个函数

    connect做了两件事

    • 把Store上的状态转化为内层傻瓜组件(Paper组件)的prop (见下面步骤2)
    • 把内层傻瓜组件中的用户动作转化为派送给Store的动作(见下面步骤3)

    import { connect } from 'react-redux'

    1. 如果只使用到store里的状态,不去改变store里的状态,定义好state传入组件
     // Paper 组件内容省略
     const Paper = () => { ... }
     const mapStateToProps = (state:any) => {
       return {
         // combineReducers组合reducer的时候该模块用的是chooseQuestion
         // 所以取出来也要用state.chooseQuestion
         selectedQuestion: state.chooseQuestion.selectedQuestion,
         questionCatalog: state.chooseQuestion.questionCatalog
       }
     }
     export default connect(
       mapStateToProps
     )(Paper)
    
    1. 如果使用到了store里的状态,并且要改变状态,定义好state和dispash方法传入组件
    // Paper 组件内容省略
     const Paper = () => { ... }
     const mapStateToProps = (state:any) => {
       return {
         selectedQuestion: state.chooseQuestion.selectedQuestion,
         questionCatalog: state.chooseQuestion.questionCatalog
       }
     }
     const mapDispatchToProps = (dispatch:any) => {
       return {
         addSelectQuestion: (question: any) => dispatch(addSelectQuestion(question)),
         addQuestionCatalog: (question: any) => dispatch(addQuestionCatalog(question))
       }
     }
    
     export default connect(
       mapStateToProps,
       mapDispatchToProps
     )(Paper)
    

    项目地址https://gitee.com/whongli/papers-composing/blob/master/redux-demo

    相关文章

      网友评论

          本文标题:redux在项目中使用

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