react 数据集中式管理- 有浅入深

文章介绍了在React中,当组件间共享状态变得复杂时,如何采用Redux进行集中式状态管理。Redux的核心概念包括store、state、action和reducer,其中action描述状态变化,reducer负责生成新state。文章还提到了中间件如redux-thunk和redux-saga处理异步操作,以及react-redux的connect方法用于连接UI组件和Reduxstore。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

像vue2一样,当全局多个组件更享同一组状态的时候,就会用到vuex,数据的集中式管理方式,那么,react 中,当遇到项目中,组件共享状态数据比较多,组件和组件之间的数据通信比较复杂,该如何入理呢?接下来,就让我们由浅入深的展开了解,react 的集中数据管理方式。

一:设计思想

  1. 试图和状态是一一对应的

  1. 所有的状态都保存在一个对象里面

二:基本概念&API

  1. store

  1. store 是保存数据的地方,整个应用只有一个store,redux 提供了createStore这个函数,用来生成store

import { createStore } from 'redux'
const store = createStore(fn)
createStore 接受另一个函数作为参数,返回新的store.
  1. state

  1. store包含所有对象,如果要得到某个时点的数据,就要对

如果想得到某个时点的数据,就要对 Store 生成快照。这种时点的数据集合,就叫做 State。

当前时刻的 state,可以通过store.getState()拿到。

redux 规定,一个state 对应一个view,只要stats相同view就相同。

import {createStore} from 'redux'
let store = createStore(fn)
let state = store.getState()
  1. action

  1. state的变化,会导致view 变化,但是用户接触不到state,只能通过view去改变state,Action 就是 View 发出的通知,表示 State 应该要发生变化了。

  1. action 是一个对象,其中type是必须的,表示action的名称

const action = {
  type: 'ADD_TODO',
  payload: 'Learn Redux'
};

可以理解为action是描述当前方式的事情,是改变state的唯一方式,就是使用 Action。它会运送数据到 Store。

  1. store.dispatch()

  1. store.dispatch()是view发送action的唯一方式。

import {createStore} from 'redux'
const store = createStore(fn)
store.dispatch({
  type: 'ADD_TODO',
  payload: 'Learn Redux'
})
  1. reducer

  1. store收到action以后,必须要给出一个新的state,这样view 才会发生变化,这种 State 的计算过程就叫做 Reducer。reducer 是一个纯函数,会接受当前state 和action 两个参数。然后返回一个新的state

const reducer = function(state,action){
    return new_state;
}
const defaultstate = 0
const reducer = function(state:defaultstate,action){
    switch(action.type){
        case 'ADD':
            return state + action.payload;
        default:
            return state
   }
}
const state = reducer(1,{
    type:'ADD',
    payload:2
})

reducer不用像上边这样手动调用,store.dispatch 发送过来一个新的action,就会自动调用reducer,得到新的stats。

纯函数

  1. 不能改写参数。

  1. 不能调用系统 I/O 的API

  1. 不能在函数中使用Date.now()或者Math.random()等不纯的方法

由于reducer是纯函数,就可以保证同样的state必须有同样的view,但正是因为这一点,reducer函数内不能随便改变state,必须返回一个全新的对象

// state 是一个对象
function reducer(state,action){
    return Object.assign({},state,{thingToChange}}
}
// state 是一个数组
function reducer(state,action){
    return [...state,newItem]
}
  1. reducer 拆分

  1. reducer 函数负责生成state,由于整个应用只有一个state对象,包含所有数据,对于大型应用来说,这个state必然十分庞大,导致reducer 函数也十分庞大。

function reducer(state={},action){
   const { type, payload } = action;
   switch (type) {
    case ADD_CHAT:
       return object.assign({},state,{
           chatLog:state.chatLog.concat(payload)
        });
    case CHANGE_STATUS:
      return Object.assign({}, state, {
        statusMessage: payload
      });
    case CHANGE_USERNAME:
      return Object.assign({}, state, {
        userName: payload
      });
    default: return state;
}

Redux 提供了一个combineReducers方法,用于 Reducer 的拆分。你只要定义各个子 Reducer 函数,然后用这个方法,将它们合成一个大的 Reducer。

import { combineReducers} from 'redux'
const chatReducer = combineReducers({
  chatLog,
  statusMessage,
  userName
})

export default todoApp;

综上所属,我们了解到了redux的基本概念,和工作原理:用户发起action,reducer 函数算出新的state,view 重新渲染。

中间件

但是,又一个关键问题没有解决,异步操作怎么办?action 发起后,reducer立即返回state,这叫同步操作,actions 发起后,reducers 过一段时间在返回state这叫异步操作。

  1. 中间件的使用

import {applyMiddleware,createStore} from 'redux'
import createLogger from 'redux-logger';
const logger = createLogger();
const store = createStore(reducer,{
    applyMiddleware(logger)
})
  1. 异步操作的基本思路

  • 操作发起时的 Action

  • 操作成功时的 Action

  • 操作失败时的 Action

操作开始时,送发一个Action,触发 State 更新为"正在操作"状态,View 重新渲染

操作结束后,再送出一个 Action,触发 State 更新为"操作结束"状态,View 再一次重新渲染

  1. redux-thunk 中间件

  1. 异步操作用户需要触发两个action,第一个是用户操作前发起,第二个是在用户操作结束后发起,如何才能在操作结束时,系统自动送出第二个Action呢?

  1. redux-saga

  1. redux-promise

react-redux

  1. connect()

  1. react-redux 提供connect 方法,用户UI组件生成容器组件。

import {connect} from 'reat-redux'
const VisibleTodoList = connect()(TodoList)

上面代码中,TodoList 是UI组件,VisibleTodoList就是由react-redux 通过connect方法自动生成的容器组件。

但是,因为没有定义业务逻辑,上面这个容器组件毫无意义,只是 UI 组件的一个单纯的包装层。为了定义业务逻辑,需要给出下面两方面的信息。

(1)输入逻辑:外部数据(既state 对象)如何转成UI组件的参数。

(2)输出逻辑:用户发出的动作如何变为action对象,从UI组件传出去。

因此,connect 方法的完整API如下图所示:

import { connect } from 'react-redux';
const VisibleTodoList = connect(
    mapStateToProps,
    mapDispatchToProps
)(TodoList)
  1. mapStateToProps

  1. mapStateToProps 第一个参数,总是state对象,还可以有第二个参数,代表容器组件的props 对象。

const mapStateToProps = (state) => {
  return {
    todos: getVisibleTodos(state.todos, state.visibilityFilter)
  }
}

const getVisibleTodos = (todos,filter) => {
    case 'SHOW_ALL':
      return todos
    case 'SHOW_COMPLETED':
      return todos.filter(t => t.completed)
    case 'SHOW_ACTIVE':
      return todos.filter(t => !t.completed)
    default:
      throw new Error('Unknown filter: ' + filter)
}
  1. mapDispatchToProps

  1. mapDispatchToProps是connect函数的第二个参数,用来建立 UI 组件的参数到store.dispatch方法的映射。也就是说,它定义了哪些用户的操作应该当作 Action,传给 Store。它可以是一个函数,也可以是一个对象。

如果mapDispatchToProps是一个函数,会得到dispatch和ownProps(容器组件的props对象)两个参数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值