在前端领域中,状态管理一直是一个非常重要的问题。随着应用程序的复杂度不断增加,用传统的方式进行状态管理已经不再适用了。这时,我们就需要一种有完整的状态管理方案,能够帮我们管理应用程序状态的解决方案。Redux 就是这样一种解决方案。
Redux 是一个 JavaScript 库,它被广泛用于构建单页应用程序(SPA)。Redux 主要被用来简化程序的状态管理,而不是用来解决其它的问题。在 Redux 中,应用程序的状态被描述为一个单一的对象。当状态发生变化时,Redux 会触发一些事件来通知应用程序状态的变化。在这篇文章中,我们将详细介绍如何使用 Redux 来实现状态管理。
1. 概述
1.1 概念
Redux 的核心概念是 Store,Action 和 Reducer。Store 是应用程序状态的唯一来源,在 Store 中存放了所有应用程序的状态。Action 是应用程序状态的变化方式,通过分发 Action,我们可以通知 Store 状态发生变化。Reducer 是一个纯 JavaScript 函数,用于处理 Action 并返回更新后的应用程序状态。
通过 Store、Action 和 Reducer,我们可以实现管理复杂状态的应用程序。
1.2 示例
下面是一个简单的 Redux 示例:
import { createStore } from 'redux' const reducer = (state = 0, action) => { switch (action.type) { case 'INCREMENT': return state + 1 case 'DECREMENT': return state - 1 default: return state } } const store = createStore(reducer) store.subscribe(() => { console.log(store.getState()) }) store.dispatch({ type: 'INCREMENT' }) store.dispatch({ type: 'INCREMENT' }) store.dispatch({ type: 'DECREMENT' })
在上面的示例中,首先我们创建了一个 reducer,它的作用是接受当前应用程序的状态和分发的 Action,并返回新的状态。在 reducer 中,我们定义了两种 Action:INCREMENT 和 DECREMENT。当我们分发 INCREMENT 和 DECREMENT Action 时,reducer 会根据 Action 的 type 属性更新应用程序的状态。
接着,我们创建了一个 Store,并传入了之前定义好的 reducer。通过 Store.dispatch 方法,我们分发了三次 Action,并每次触发了 Store.subscribe 方法,输出了 Store 的当前状态。
最后运行代码,可以得到以下输出:
1 2 1
1.3 安装
在使用 Redux 之前,我们需要先安装它。可以通过 npm 来安装 Redux:
npm install redux
2. Redux 核心概念
2.1 Store
Store 是 Redux 中的核心概念。它存储了所有的应用程序状态,并提供了一些用于管理状态的方法。在 Redux 中,Store 中的所有状态都是只读的,唯一的改变方式是分发 Action。
在 Redux 中,Store 是通过 createStore 函数创建的。createStore 函数接受一个 reducer,用于处理 Action 并返回新的状态。下面是一个简单的 createStore 示例:
import { createStore } from 'redux' const reducer = (state = 0, action) => { switch (action.type) { case 'INCREMENT': return state + 1 case 'DECREMENT': return state - 1 default: return state } } const store = createStore(reducer)
在上面的代码中,我们首先定义了一个 reducer,用于处理 Action 并返回新的应用程序状态。然后,我们利用这个 reducer 创建了一个 Store,并把它存储在变量 store 中。
2.2 Action
在 Redux 中,Action 是应用程序的状态变化方式。Action 本质上是一个具有 type 属性的纯 JavaScript 对象。当需要改变应用程序状态时,我们只需要分发一个 Action,Redux 将自动触发 Store 更新应用程序的状态。
下面是一个例子:
store.dispatch({ type: 'INCREMENT' })
在上面的代码中,我们通过 store.dispatch 方法分发了一个 Action,它的 type 属性是 INCREMENT。当 Store 接收到 Action 后,会调用之前定义的 reducer 函数,并根据返回的新状态更新应用程序的状态。
2.3 Reducer
Reducer 是一个纯 JavaScript 函数,用于处理 Action 并返回新的应用程序状态。在 Redux 中,Reducer 是单向的,它不会改变传递给它的任何参数。Reducer 只要接受两个参数:原始状态(或当前状态)和 Action。它应该返回一个新的状态,不会改变原始状态。
在 Redux 中,Reducer 应该是一个纯 JavaScript 函数。这意味着,它不应该有任何副作用,例如修改输入或全局变量、请求网络等等。它应该只是一个纯粹的函数,它只依赖于传递给它的参数。
下面是一个简单的 reducer 实现:
const reducer = (state = 0, action) => { switch (action.type) { case 'INCREMENT': return state + 1 case 'DECREMENT': return state - 1 default: return state } }
在上面的例子中,我们定义了一个 reducer 函数,它接受两个参数 state 和 action。在 reducer 函数中,我们使用 switch 映射所有可能的 Action,而不需要使用 if 语句。当 reducer 函数接收到一个 Action 时,它将根据 Action 的 type 属性更新应用程序的状态,并返回新的状态值。
2.4 combineReducers
在 Redux 中,combineReducers 是一个用于将由多个 reducer 组成的状态合并成单一状态树的辅助函数。combineReducers 接受一个对象作为参数,该对象包含多个 reducer,每个 reducer 用于处理自己的一部分状态。
下面是一个 combineReducers 的示例:
import { combineReducers, createStore } from 'redux' const todoReducer = (state = [], action) => { switch (action.type) { case 'ADD_TODO': return [...state, { id: action.id, text: action.text }] case 'REMOVE_TODO': return state.filter(todo => todo.id !== action.id) default: return state } } const visibilityFilterReducer = (state = 'SHOW_ALL', action) => { switch (action.type) { case 'SET_VISIBILITY_FILTER': return action.filter default: return state } } const rootReducer = combineReducers({ todos: todoReducer, visibilityFilter: visibilityFilterReducer }) const store = createStore(rootReducer)
在上面的代码中,我们首先定义了两个 reducer,用于处理两种不同的状态:todoReducer 和 visibilityFilterReducer。然后,我们使用 combineReducers 函数将它们组合起来,并返回一个新的 reducer(rootReducer)。在最后一行,我们使用这个 rootReducer 创建了 Store。
最后的 Store 的状态结构如下:
{ todos: [], visibilityFilter: 'SHOW_ALL' }
3. React Redux
React Redux 是一个用于将 Redux 与 React 框架相结合的库。它提供了一些帮助 React 应用程序与 Redux 进行集成的组件,例如 Provider 和 connect。
3.1 Provider
Provider 是 React Redux 提供的一个跨组件的组件。它接受一个名为 store 的属性,用于传递 Redux 的 Store 实例。Provider 的作用是让子组件能够访问到 Store。
下面是一个 Provider 的示例:
import React from 'react' import ReactDOM from 'react-dom' import { Provider } from 'react-redux' import { createStore } from 'redux' import App from './App' import rootReducer from './reducers' const store = createStore(rootReducer) ReactDOM.render( <Provider store={store}> <App /> </Provider>, document.getElementById('root') )
在上面的代码中,我们首先使用 createStore 函数创建了一个 Store,然后将它传递到 Provider 组件中。在 Provider 的子组件中,我们可以通过 connect 函数来连接 Store 和组件。
3.2 connect
connect 函数是 React Redux 提供的一个函数,用于将 React 组件与 Redux 的 Store 进行连接。connect 函数接受两个参数:mapStateToProps 和 mapDispatchToProps。
mapStateToProps 函数用于将 Redux 的 Store 的部分状态映射到 React 的 Props 对象中。mapDispatchToProps 函数用于将 Redux 的 ActionCreator 函数映射到 React 的 Props 对象中。
下面是一个 connect 函数的示例:
import React from 'react' import { connect } from 'react-redux' const Counter = ({ counter, increment, decrement }) => ( <div> <h1>{counter}</h1> <button onClick={increment}>+</button> <button onClick={decrement}>-</button> </div> ) const mapStateToProps = state => ({ counter: state }) const mapDispatchToProps = dispatch => ({ increment: () => dispatch({ type: 'INCREMENT' }), decrement: () => dispatch({ type: 'DECREMENT' }) }) export default connect(mapStateToProps, mapDispatchToProps)(Counter)
在上面的代码中,我们首先定义了一个 Counter 组件,它接受 counter、increment 和 decrement 三个 Props。然后,我们定义了两个函数 mapStateToProps 和 mapDispatchToProps,并将它们传递给 connect 函数。最后,我们将 Counter 组件导出并使用 connect 函数对其进行连接。
4. 总结
在本文中,我们详细介绍了 Redux 的核心概念:Store、Action 和 Reducer。我们还通过示例代码演示了如何使用 Redux 来进行状态管理,以及如何使用 React Redux 将 Redux 集成到 React 应用程序中。
Redux 是一个非常有用的库,可以帮助我们管理复杂的应用程序状态。虽然它可能需要一些学习和理解,但一旦掌握了它,就可以轻松地管理任何规模的应用程序状态。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65a3a713add4f0e0ffbc9d49