×

React项目:如何优雅使用Redux中的react-redux

作者:Terry2022.09.13来源:Web前端之家浏览:7309评论:0
关键词:React

Redux是用于数据状态管理,而react是一个视图层面的库。

如果将两者连接在一起,可以使用官方推荐React-redUX库,其具有高效且灵活的特性。

React-redux将组件分成:

  • 容器组件:存在逻辑处理

  • UI 组件:只负责现显示和交互,内部不处理逻辑,状态由外部控制

通过redux将整个应用状态存储到store中,组件可以派发dispatch行为action给store

其他组件通过订阅store中的状态state来更新自身的视图

React 实际上只是 ui 框架,通过 JSX 生成动态 DOM 渲染 UI,没有架构、没有模板、没有设计模式、没有路由、也没有数据管理。所以需要借助其他工具。

redux

npm install redux --save

什么是 redux ?

Redux 是 javascript 状态容器,提供可预测化的状态管理。可以理解为全局数据状态管理工具,用来做组件通信等。

为什么使用 redux ?

当没有使用 redux 时兄弟组件间传值将很麻烦,代码很复杂冗余。使用 redux 定义全局单一的数据 Store,可以自定义 Store 里面存放哪些数据,整个数据结构也是自己清楚的。

redux 工作流 ?

image.png

    store:推送数据的仓库

    reducer:帮助 store 处理数据的方法(初始化、修改、删除)

    actions:数据更新的指令

    react 组件(UI):订阅 store 中的数据

redux 用法:

import { createStore } from 'redux'

/*
 * 这是一个 reducer,形式为 (state, action) => state 的纯函数。描述了 action 如何把 state 转变成下一个 state。
 * state 的形式取决于你,可以是基本类型、数组、对象、甚至是 Immutable.JS 生成的数据结构。
 * 当 state 变化时需要返回全新的对象,而不是修改传入的参数。
 */
function counter(state = 0, action) {
  switch (action.type) {
  case 'INCremENT':
    return state + 1
  case 'DECRemENT':
    return state - 1
  default:
    return state;
  }
}

// 创建 Redux store 来存放应用的状态
// API 是 { subscribe, dispatch, getState }
const store = createStore(counter);

// 可以手动订阅更新,也可以事件绑定到视图层。
store.subscribe(() =>
  const sotreState = store.getState()
  ......
)

// 改变内部 state 惟一方法是 dispatch 一个 action。
store.dispatch({ type: 'INCREMENT' })
store.dispatch({ type: 'DECREMENT' })

redux 三大原则:

单一数据源:整个应用的 state 存放在唯一的一个 store 中。store.getState()

state 是只读的,唯一改变 state 的方法就是触发 action,action 是一个用于描述已发生事件的普通对象。

store.dispatch({
  type: 'COMPletE_TODO',
  index: 1
})

使用纯函数来执行修改(reducer:接收先前的 state 和 action,并返回新的 state)。

function visibilityfilter(state = 'SHOW_ALL', action) {
    switch (action.type) {
      case 'SET_VISIBILITY_FILTER':
        return action.filter
      default:
        return state
    }
  }
 
  function todos(state = [], action) {
    switch (action.type) {
      case 'ADD_TODO':
        return [
          ...state,
          {
            text: action.text,
            completed: false
          }
        ]
      case 'COMPLETE_TODO':
        return state.map((todo, index) => {
          if (index === action.index) {
            return Object.assign({}, todo, {
          completed: true
            })
          }
          return todo
        })
      default:
        return state
    }
  }
 
  import { combineReducers, createStore } from 'redux'
  const reducer = combineReducers({ visibilityFilter, todos })
  const store = createStore(reducer)

React-Redux

npm install react-redux --save

React-Redux 是 Redux 的官方 React 绑定库。它能够使你的 React 组件从 Redux store 中读取数据,并且向 store 分发 actions 以更新数据

React-Redux 将所有组件分成两大类:UI 组件和容器组件。UI 组件负责 UI 的呈现,容器组件负责管理数据和逻辑。

    UI 组件:只负责 UI 的呈现,不带有任何业务逻辑;没有状态(即不使用 this.state 这个变量);所有数据都由参数 this.props 提供;不使用任何 Redux 的 API

    容器组件:负责管理数据和业务逻辑,不负责 UI 的呈现;带有内部状态;使用 Redux 的 API。

React-Redux 规定,所有的 UI 组件都由用户提供,容器组件则是由 React-Redux 自动生成。也就是说,用户负责视觉层,状态管理则是全部交给它。

connect()

import { connect } from 'react-redux'
const Visibletodolist = connect(mapStateToprops, mapDispatchToPRops)(Todolist)
上面 VisibleTodoList 便是 UI 组件 TodoList 通过 connect 方法自动生成的容器组件。

connect 方法接受两个参数:mapStateToProps 和 mapDispatchToProps。它们定义了 UI 组件的业务逻辑。前者负责输入逻辑,即将 state 映射到 UI 组件的参数 props,后者负责输出逻辑,即将用户对 UI 组件的操作映射成 Action。

mapStateToProps()

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

mapStateToProps 是一个函数,它接受 state 作为参数,返回一个对象。这个对象有一个 todos 属性,代表 UI 组件的同名参数,后面的 getVisibleTodos 也是一个函数,可以从 state 算出 todos 的值。
mapStateToProps 建立一个从(外部的)state 对象到(UI 组件的)props 对象的映射关系。执行后应该返回一个对象,里面的每一个键值对就是一个映射。

mapDispatchToProps()

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

是函数则会得到 dispatch 和 ownProps(容器组件的 props 对象)两个参数。

const mapDispatchToProps = (dispatch, ownProps) => {
    return {
      onClick: () => {
        dispatch({
          type: 'SET_VISIBILITY_FILTER',
          filter: ownProps.filter,
        })
      }
    }
}

是一个对象,它的每个键名也是对应 UI 组件的同名参数,键值应该是一个函数,会被当作 Action creator ,返回的 Action 会由 Redux 自动发出。

const mapDispatchToProps = {
    onClick: (filter) => {
      type: 'SET_VISIBILITY_FILTER',
      filter: filter
    };
  }

<Provider> 组件

connect 方法生成容器组件以后,需要让容器组件拿到 state 对象,才能生成 UI 组件的参数。

React-Redux 提供 Provider 组件,使整个 APP 访问到 Redux store 中的数据 即state。

// src/index.tsx
import React from 'react'
import Reactdom from 'react-dom'
import reportWEBVitals from './reportWebVitals'
import { Provider } from 'react-redux'
import store from './redux/store'
import app from './App'

ReactDOM.render(
    <React.Strictmode>
        <Provider store={store}>
            <App />
        </Provider>
    </React.StrictMode>,
    document.getElementById('root')
)

reportWebVitals()


赏您的支持是我们创作的动力!
温馨提示:本文作者系Terry ,经Web前端之家编辑修改或补充,转载请注明出处和本文链接:
https://jiangweishan.com/article/react20220913a1.html

网友评论文明上网理性发言 已有0人参与

发表评论: