• 如何优雅地在React项目中使用Redux


    前言

    或许你当前的项目还没有到应用Redux的程度,但提前了解一下也没有坏处,本文不会安利大家使用Redux

    概念

    首先我们会用到哪些框架和工具呢?

    React

    UI框架

    Redux

    状态管理工具,与React没有任何关系,其他UI框架也可以使用Redux

    react-redux

    React插件,作用:方便在React项目中使用Redux

    react-thunk

    中间件,作用:支持异步action

    目录结构

    Tips:与Redux无关的目录已省略

    1 |--src
    2     |-- store                Redux目录
    3         |-- actions.js
    4         |-- index.js
    5         |-- reducers.js
    6         |-- state.js
    7     |-- components         组件目录
    8         |-- Test.jsx
    9     |-- App.js               项目入口

    准备工作

    第1步:提供默认值,既然用Redux来管理数据,那么数据就一定要有默认值,所以我们将state的默认值统一放置在state.js文件

     1 // state.js
     2 
     3 // 声明默认值
     4 // 这里我们列举两个示例
     5 // 同步数据:pageTitle
     6 // 异步数据:infoList(将来用异步接口获取)
     7 export default {
     8     pageTitle: '首页',
     9     infoList: []
    10 }  

    第2步:创建reducer,它就是将来真正要用到的数据,我们将其统一放置在reducers.js文件

     1 // reducers.js
     2 
     3 // 工具函数,用于组织多个reducer,并返回reducer集合
     4 import { combineReducers } from 'redux'
     5 // 默认值
     6 import defaultState from './state.js'
     7 
     8 // 一个reducer就是一个函数
     9 function pageTitle (state = defaultState.pageTitle, action) {
    10   // 不同的action有不同的处理逻辑
    11   switch (action.type) {
    12     case 'SET_PAGE_TITLE':
    13       return action.data
    14     default:
    15       return state
    16   }
    17 }
    18 
    19 function infoList (state = defaultState.infoList, action) {
    20   switch (action.type) {
    21     case 'SET_INFO_LIST':
    22       return action.data
    23     default:
    24       return state
    25   }
    26 }
    27 
    28 // 导出所有reducer
    29 export default combineReducers({
    30     pageTitle,
    31     infoList
    32 })

    第3步:创建action,现在我们已经创建了reducer,但是还没有对应的action来操作它们,所以接下来就来编写action

     1 // actions.js
     2 
     3 // action也是函数
     4 export function setPageTitle (data) {
     5   return (dispatch, getState) => {
     6     dispatch({ type: 'SET_PAGE_TITLE', data: data })
     7   }
     8 }
     9 
    10 export function setInfoList (data) {
    11   return (dispatch, getState) => {
    12     // 使用fetch实现异步请求
    13     window.fetch('/api/getInfoList', {
    14         method: 'GET',
    15         headers: {
    16             'Content-Type': 'application/json'
    17         }
    18     }).then(res => {
    19         return res.json()
    20     }).then(data => {
    21         let { code, data } = data
    22         if (code === 0) {
    23             dispatch({ type: 'SET_INFO_LIST', data: data })
    24         }
    25     })
    26   }
    27 }

    最后一步:创建store实例

     1 // index.js
     2 
     3 // applyMiddleware: redux通过该函数来使用中间件
     4 // createStore: 用于创建store实例
     5 import { applyMiddleware, createStore } from 'redux'
     6 
     7 // 中间件,作用:如果不使用该中间件,当我们dispatch一个action时,需要给dispatch函数传入action对象;但如果我们使用了这个中间件,那么就可以传入一个函数,这个函数接收两个参数:dispatch和getState。这个dispatch可以在将来的异步请求完成后使用,对于异步action很有用
     8 import thunk from 'redux-thunk'
     9 
    10 // 引入reducer
    11 import reducers from './reducers.js'
    12 
    13 // 创建store实例
    14 let store = createStore(
    15   reducers,
    16   applyMiddleware(thunk)
    17 )
    18 
    19 export default store

    至此,我们已经完成了所有使用Redux的准备工作,接下来就在React组件中使用Redux

    开始使用

    首先,我们来编写应用的入口文件APP.js

     1 // App.js
     2 
     3 import React from 'react'
     4 import ReactDOM from 'react-dom'
     5 
     6 // 引入组件
     7 import TestComponent from './components/Test.jsx'
     8 
     9 // Provider是react-redux两个核心工具之一,作用:将store传递到每个项目中的组件中
    10 // 第二个工具是connect,稍后会作介绍
    11 import { Provider } from 'react-redux'
    12 // 引入创建好的store实例
    13 import store from '@/store/index.js'
    14 
    15 // 渲染DOM
    16 ReactDOM.render (
    17   (
    18     <div>
    19         {/* 将store作为prop传入,即可使应用中的所有组件使用store */}
    20         <Provider store = {store}>
    21           <TestComponent />
    22         </Provider>
    23     </div>
    24   ),
    25   document.getElementById('root')
    26 )

    最后是我们的组件:Test.jsx

     1 // Test.jsx
     2 
     3 import React, { Component } from 'react'
     4 
     5 // connect方法的作用:将额外的props传递给组件,并返回新的组件,组件在该过程中不会受到影响
     6 import { connect } from 'react-redux'
     7 
     8 // 引入action
     9 import { setPageTitle, setInfoList } from '../store/actions.js'
    10 
    11 class Test extends Component {
    12   constructor(props) {
    13     super(props)
    14   }
    15 
    16   componentDidMount () {
    17     let { setPageTitle, setInfoList } = this.props
    18     
    19     // 触发setPageTitle action
    20     setPageTitle('新的标题')
    21     
    22     // 触发setInfoList action
    23     setInfoList()
    24   }
    25 
    26   render () {
    27     // 从props中解构store
    28     let { pageTitle, infoList } = this.props
    29     
    30     // 使用store
    31     return (
    32       <div>
    33         <h1>{pageTitle}</h1>
    34         {
    35             infoList.length > 0 ? (
    36                 <ul>
    37                     {
    38                         infoList.map((item, index) => {
    39                             <li>{item.data}</li>
    40                         })
    41                     }
    42                 </ul>
    43             ):null
    44         }
    45       </div>
    46     )
    47   }
    48 }
    49 
    50 // mapStateToProps:将state映射到组件的props中
    51 const mapStateToProps = (state) => {
    52   return {
    53     pageTitle: state.pageTitle,
    54     infoList: state.infoList
    55   }
    56 }
    57 
    58 // mapDispatchToProps:将dispatch映射到组件的props中
    59 const mapDispatchToProps = (dispatch, ownProps) => {
    60   return {
    61     setPageTitle (data) {
    62         // 如果不懂这里的逻辑可查看前面对redux-thunk的介绍
    63         dispatch(setPageTitle(data))
    64         // 执行setPageTitle会返回一个函数
    65         // 这正是redux-thunk的所用之处:异步action
    66         // 上行代码相当于
    67         /*dispatch((dispatch, getState) => {
    68             dispatch({ type: 'SET_PAGE_TITLE', data: data })
    69         )*/
    70     },
    71     setInfoList (data) {
    72         dispatch(setInfoList(data))
    73     }
    74   }
    75 }
    76 
    77 export default connect(mapStateToProps, mapDispatchToProps)(Test)

    Redux三大原则

    • 单一数据源
      整个应用的 state 被储存在一棵 object tree 中,并且这个 object tree 只存在于唯一一个 store 中
    • State 是只读的
      唯一改变 state 的方法就是触发 action,action 是一个用于描述已发生事件的普通对象
    • 使用纯函数来执行修改
      为了描述 action 如何改变 state tree ,你需要编写 reducers

    结语

    以上就是在React项目中使用Redux的简单示例,文中代码可能会有编写错误,欢迎指正,同事希望本文对大家有所帮助

    参考

    原文出处:如何优雅地在React项目中使用Redux

  • 相关阅读:
    WinForm画网格并填充颜色
    CodeCombat最后一题GridMancer
    TeeChart缩放
    TeeChart的网络资料
    TeeChart设置图表的标题
    TeeChart取消3D
    TeeChart的坐标轴
    TeeChart入门
    win7下配置IIS
    C#中的编译开关
  • 原文地址:https://www.cnblogs.com/sampapa/p/8134086.html
Copyright © 2020-2023  润新知