React Redux 是前端开发中常用的一种状态管理库,能够进行全局数据传递和状态管理。在实际应用中,我们也发现 React Redux 这个库虽然能够实现很多功能,但是一些不合理的使用方式会引起应用运行效率低下,数据传递混乱等问题。在本文中,我们将分享 React Redux 的使用心得并且介绍优化实践。
基本概念
在使用 React Redux 之前,需要了解一些基本概念。
Store
Store 是 React Redux 应用中存储数据的地方,类似于一个数据库。
Action
Action 是描述应用中发生变化的对象。Action 是由命名类型和一些对应的数据组成。
Reducer
Reducer 是应用中处理 Action 的函数。它可以更新 Store 中的数据。
Provider
Provider 是 React Redux 应用的顶层组件,它把 Store 对象传递到 React 组件中。
Connect
Connect 是一个函数,将 React 组件连接到 Store 中,并且在组件中提供 dispatch 和 state。
实践
下面我们举一个具体使用 React Redux 的案例,以便于更好地理解上述概念。
Store 定义
我们首先需要定义一个 store,用于存放所有管理的状态。
import { createStore } from 'redux' import rootReducer from './reducers' const store = createStore(rootReducer) export default store
我们通过 createStore 方法创建了一个 Store,并传入一个 rootReducer 函数,它用于处理所有的 Action。当然,我们也可以根据需要传入更多参数,比如中间件等。
Action 创建函数
我们需要创建一些 Action 的创建函数。比如,当需要在 Store 中设置一个用户信息时,可以这样写。
export function setUserInfo (info) { return { type: 'SET_USER_INFO', payload: { info } } }
这个函数返回一个包含 type 和 payload 的对象,payload 中存储了需要设置的用户信息。
Reducer 处理函数
我们需要在应用中定义 Reducer 函数,以处理 Action。对于上面定义的 SET_USER_INFO 这个 Action,我们可以这样写 Reducer 函数。
-- -------------------- ---- ------- ------ -------- -------- ------ - --- ------- - ------ ------------- - ---- ---------------- ------ ----------------- ------ - ----------------- -- -------- ------ ----- - -
这个函数接收一个 state 和一个 action。它通过 switch 分支处理不同的 action 类型,将当前的 state 和参数 object 进行合并处理返回一个新的 state,最后将新的 state 返回到 Store 中。
Provider 组件
我们需要一个 Provider 组件,将创建好的 Store 对象传递到应用中。
-- -------------------- ---- ------- ------ - -------- - ---- ------------- ------ ----- ---- --------- -------- --- -- - ------ - --------- -------------- -------- ------------- ----------- - -
Provider 组件接收一个 store 对象,它将 store 通过 context API 传递到下层组件中。
Connect 函数
最后,我们需要将 React 组件和 Redux Store 连接起来。我们可以使用 Connect 这个 HOC。
-- -------------------- ---- ------- ------ - ------- - ---- ------------- ------ - ----------- - ---- ------------ ----- -------- ------- --------- - ------ -- - ------ ---------------------------- - - -------- --------------- ------- - ------ - ----- ------------------- - - -------- ------------------ ---------- - ------ - ------------ ------ -- --------------------------- - - ------ ------- ------------------------ -----------------------------
通过 Connect 来实现组件到 Redux 的状态映射。
优化实践
在实践过程中我们发现有些使用不合理的方式会影响性能并引起其他问题。这里我们提供一些优化实践。
Add shouldComponentUpdate
Life Cycle To Improve Efficiency
在 Connect 连接 Store 的高阶组件中,React 组件会在 Store 发生变化时不断地渲染。然而由于 props 变化不一定导致 UI 变化,我们很有可能不必在每次变化时都重新渲染组件。
因此我们可以实现 shouldComponentUpdate 函数来避免无效渲染。这个这个函数会在每次组件更新前检查新旧属性的变化,如果没有变化则不会执行渲染操作。
-- -------------------- ---- ------- ----- -------- ------- --------- - --------------------- ----------- ---------- - -- -- ---- ----------- ------ --------------- --- -------------- - ------ -- - ------ ---------------------------- - - -------- --------------- ------- - ------ - ----- ------------------- - - ------ ------- ----------------------------------
拆分 Smaller Reducer
当应用的状态变得复杂时,单个 reducer 可能会变得庞大难以维护。我们可以将 reducer 拆分成多个子 reducer,然后再合并到一个根 reducer 中。这样可以提高代码的合理性,降低了代码的复杂度。
-- -------------------- ---- ------- ------ - --------------- - ---- ------- ------ - ---- - ---- -------- ------ - ------- - ---- ----------- ----- ----------- - ----------------- ----- ------- -- ------ ------- -----------
使用 Reselect 库实现状态缓存
当一个状态需要在多个组件中使用时,我们通常需要通过 props 进行多次传递。这样会使代码变得冗余,不易于维护。这时我们可以使用 Reselect 库,它提供了一种缓存状态的方式。
import { createSelector } from 'reselect' const selectUser = state => state.user export const selectUserName = createSelector( selectUser, user => user.name )
在上面的代码中,selectUser 函数返回的是全局的 Store 对象中的 user 键值对,而 selectUserName 返回的则是 user 中的 name 值。
当多个组件都对 name 进行获取时,可以使用 selectUserName 来快速获取缓存中的值。
总结
在这篇文章中,我们学习了如何使用 React Redux 构建一个应用。同时也分享了一些优化实践,希望对大家有所启发。当然 React Redux 架构的复杂度远远不止这些,还需要我们通过自己的实践来进行更深层次的学习和探索。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/651d0c5195b1f8cacd490577