发布于 2026-01-06 7 阅读
0

React - Redux 七分钟速成指南!注意!!!概述 Redux Redux 基础 Redux 模式 React 和 Redux(计数器应用)何时使用 Redux 结论

React - Redux 七分钟速成

注意力!!!

概述

重制版

Redux基础知识

Redux模式

React 和 Redux(计数器应用)

何时使用 Redux

结论

替代文字

注意力!!!

本文中的代码是 Redux官方文档 Redux.js.org中提到的 Redux 模式的有效实现。不过,Redux 还提供了一个增强型工具包,建议在使用 React 和 Redux 进行开发时使用该工具包。最终选择哪种方式完全取决于您自己。您可以点击链接了解更多关于reduxjs/toolkit 的信息。

概述

在本文中,我将介绍 Redux 的一些基本概念,以及如何使用 React 和 Redux 构建一个简单的应用程序(计数器应用程序)。

重制版

Redux是 JavaScript 应用的可预测状态容器。这意味着,无论应用内发生何种变化,包括数据和 UI 的变化,这些变化都会被包含在一个名为state的 JavaScript 对象中。state 通常被称为“单一数据源”,因为它永远不会被修改或改变,而是会被重新创建。有了单一数据源,我们就能更好地预测应用在特定时刻的状态。

Redux基础知识

在深入探讨应用程序之前,让我们先来了解一些 Redux 的基础知识。

状态

状态是一个 JavaScript 对象,它代表 Redux 应用的完整状态。它可以是一个包含单个值的简单对象,也可以是一个更复杂的对象

{counter: 0}
Enter fullscreen mode Exit fullscreen mode

整个应用程序都可以访问状态,状态由一个名为 store 的集中式容器进行管理。访问 store 的唯一方法是通过 dispatch 一个action

行动

操作是商店应如何改变状态的描述。

{
  type: 'INCREMENT',
  value: 5, 
}
Enter fullscreen mode Exit fullscreen mode

应用程序内部的变化由 action 的type属性来识别。所有 action 都具有 type 属性。type 属性告诉 store 如何响应并重新创建状态。状态的创建由reducer处理。

减速器

reducer 是一个 JavaScript 函数,它会根据某种操作类型创建一个新的状态。

const reducer = (state = initialState, action) => {
    switch (action.type) {
        case actionType.ADD:
            return {
                ...state,
                counter: state.counter + 1
          }
    }
    return state;
}
Enter fullscreen mode Exit fullscreen mode

Reducer 通常被称为纯 JavaScript 函数。纯 JavaScript 函数是指对于相同的输入,始终返回相同输出的函数。之所以称为纯函数,是因为它们具有可预测性,并且不包含任何副作用,例如网络或数据库调用。Reducer 最重要的任务是为store重新创建状态

店铺

store是一个 JavaScript 对象用于保存应用程序的状态。一个 Redux 应用中应该只有一个 store。

{
  dispatch: Dispatch
  getState: () => State
  subscribe: (listener: () => void) => () => void
  replaceReducer: (reducer: Reducer) => void
}
Enter fullscreen mode Exit fullscreen mode

存储方法

  • dispatch(action):派遣行动
  • getState()返回当前状态
  • subscribe(listener)添加一个变更监听器
  • replaceReducer(nextReducer):替换减速器

Redux模式

Redux模式可以可视化如下。
替代文字

React 和 Redux(计数器应用)

在本节中,我将介绍如何使用 React 和 Redux 构建一个简单的计数器应用程序。要查看应用程序代码,请点击此处。

入门

首先,我将使用npx创建一个基本的 React 应用,并安装所需的依赖项:react-redux 和 redux

npx create-react-app redux-practice
cd redux-practice
npm i react-redux redux
Enter fullscreen mode Exit fullscreen mode

接下来,我将创建三个新目录来管理我的应用程序的文件。

mkdir src/store
mkdir src/containers
mkdir src/components
Enter fullscreen mode Exit fullscreen mode
  • src/storeRedux store 需要 Reducer 和 actions
  • src/containers- 连接到 Redux store 的组件
  • src/components- 展示层组件

我将首先着手处理位于 store 目录中的 actions 和 reducers。

touch src/store/actions.js
touch src/store/reducers.js
Enter fullscreen mode Exit fullscreen mode

首先,我将定义我的操作。为了简单起见,便于演示,这个应用程序的操作不会很多。

src/store/actions.js
export const ADD = 'ADD';
export const SUBTRACT = 'SUBTRACT';
Enter fullscreen mode Exit fullscreen mode

接下来,我将创建 store 所需的 reducer 函数。

src/store/reducers.js
import * as actionType from './actions';
const initialState = {
    counter: 0
}

const reducer = (state = initialState, action) => {
    switch (action.type) {
        case actionType.ADD:
            return {
                ...state,
                counter: state.counter + 1
            }
        case actionType.SUBTRACT:
            return {
                ...state,
                counter: state.counter - 1
            }
        default:
            return state
    }
}
export default reducer;
Enter fullscreen mode Exit fullscreen mode

在上面的代码片段中,我从actions.js导入了所有 actions ,然后创建了一个 state 变量来初始化这个 reducer 的状态,并创建了我的 reducer 函数。这个 reducer 函数接受两个参数:state和 action。state 未初始化时,会被设置为 initialState;action会在 dispatch 一个 action 时传入。我会使用 switch state 来判断 action 的类型,并使用actions.js中的 actions来处理每种情况。

现在我已经创建了 reducer 和 actions,接下来要创建 store。store 应该创建在顶层组件中,在本例中是index.js。

src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import reducer from './store/reducers';
import './index.css';
import App from './App';

const store = createStore(reducer);

ReactDOM.render(
  <React.Fragment>
    <Provider store={store}><App /></Provider>
  </React.Fragment>,
  document.getElementById('root')
);
Enter fullscreen mode Exit fullscreen mode

index.js文件中,我从 redux 导入了createStore,并从 react-redux 导入了Provider。我还导入了 createStore 函数所需的 reducer。createStore 函数接收 reducer 作为参数,并返回 redux store。我使用了 Provider,它有一个名为store 的prop ,我将上面创建的 store 传递给 Provider 的这个 prop。此时,整个 React 应用都可以访问 redux store 了。

接下来,我将创建两个组件来表示计数器应用程序。

mkdir src/components/CounterButton
mkdir src/components/CounterLabel
touch src/components/CounterButton/CounterButton.js
touch src/components/CounterLabel/CounterLabel.js
Enter fullscreen mode Exit fullscreen mode

这些组件是展示组件,所以它们会非常简单。

计数器按钮.js
import React from 'react';
import './CounterButton.css';

function CounterButton(props) {
    return (
        <div className="CounterButton">
            <button
                type="button"
                onClick={props.clicked}
                className="btn btn-primary">
                {props.label}
            </button>
        </div>
    )
}
export default CounterButton;
Enter fullscreen mode Exit fullscreen mode
CounterLabel.js
import React from 'react';

import './CounterLabel.css'

function CounterLabel(props) {
    return (
        <div className='CounterLabel'>
            {props.value}
        </div>
    )
}

export default CounterLabel;
Enter fullscreen mode Exit fullscreen mode

接下来,我将创建计数器组件,并将其连接到 redux store。

touch src/containers/Counter.js
Enter fullscreen mode Exit fullscreen mode
Counter.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
import * as actionType from '../store/actions';
import CounterLabel from
    '../components/CounterLabel/CounterLabel';
import CounterButton from
    '../components/CounterButton/CounterButton';

import './Counter.css';

class Counter extends Component {
    render() {
        return (
            <div className="Counter">
                <CounterLabel value={this.props.ctr} />
                <CounterButton
                    clicked={this.props.onAdd}
                    label="Add" />
                <CounterButton
                    clicked={this.props.onSubtract}
                    label="Subtract" />
            </div>
        )
    }
}

const mapStateToProps = state => {
    return {
        ctr: state.counter
    }
}

const mapDispatchToProps = dispatch => {
    return {
        onAdd: () => dispatch({ type: actionType.ADD }),
        onSubtract: () => dispatch({type: actionType.SUBTRACT})
    }
}

export default connect(
    mapStateToProps,
    mapDispatchToProps
)(Counter);

Enter fullscreen mode Exit fullscreen mode

在Counter.js文件中,我从react-redux包导入了 connect 函数,并在文件末尾直接在组件中使用它。connect 函数接受两个参数:第一个参数mapStateToProps,用于选择组件所需的状态;第二个参数mapDispatchToProps,用于将 action 分发到 store。onAddonSubtract函数作为 props 传递给 ControlButtons 组件,点击这些按钮时,会将各自的 action 分发到 store。至此,一个简单的计数器应用程序就完成了

何时使用 Redux

本文中的应用示例非常简单,仅供学习参考。大多数情况下,这种规模的应用并不需要使用 Redux。状态管理系统更适合大型应用,因为大型应用的状态管理往往比较复杂难懂。以下是我从Academind的 Maxillian 那里了解到的关于何时使用 Redux 的一些要点。

  1. 本地 UI 状态 - 不推荐使用 Redux
  2. 持久化状态 - Redux 可用于存储您需要显示的数据
  3. 客户端状态 - 考虑使用 Redux

替代文字

结论

一如既往,请多保重。如果您觉得这篇文章有用,请留下评分;如果您有任何疑问,请留言,我会尽快回复。

文章来源:https://dev.to/meddy672/react-redux-in-less-then-7-minutes-had