广告
返回顶部
首页 > 资讯 > 精选 >React中如何使用Redux
  • 227
分享到

React中如何使用Redux

2023-07-02 00:07:18 227人浏览 八月长安
摘要

这篇文章主要讲解了“React中如何使用Redux”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“React中如何使用Redux”吧!Redux 是一种状态容器 js 库,提供可预测的状态管理

这篇文章主要讲解了“React中如何使用Redux”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“React中如何使用Redux”吧!

    Redux 是一种状态容器 js 库,提供可预测的状态管理,经常和 React 配合来管理应用的全局状态,进行响应式组件更新。

    Redux 一般来说并不是必须的,只有在项目比较复杂的时候,比如多个分散在不同地方的组件使用同一个状态。对于这种情况,如果通过 props 层层传递,代码会变得不可维护,这时候我们可以考虑使用 Redux 这类状态管理库。

    不使用 Redux 的写法

    我们创建一个 User 组件,显示用户名,并支持设置用户名。先看看不使用 Redux 的写法。

    import { Component, createRef } from 'react';class User extends Component {  state = { username: '前端西瓜哥' };  inputRef = createRef();  setUsername = () => {    this.setState({ username: this.inputRef.current.value });  };  render() {    return (      <div>        <div>用户名: {this.state.username}</div>        <input ref={this.inputRef} type="text" />        <button onClick={this.setUsername}>设置用户名</button>      </div>    );  }}export default User;

    下面我们改造一下这个组件,将状态迁移到 Redux 里。

    最底层的写法

    Redux 是和框架无关的,我们先看看只用 Redux 库的写法。

    demo:codesandbox.io/s/redux-pla&hellip;

    首先我们创建一个 reducer。

    // user_reducer.jsimport { SET_USERNAME } from './constants';// 初始值const defaultState = {  name: '前端西瓜哥',  age: 88};// 用于修改 user 状态的 reducerexport const userReducer = (preState = defaultState, action) => {  switch (action.type) {    case SET_USERNAME: // type 值都统一放到 constants      return { ...preState, name: action.payload };    // 这里还可以根据需要,添加类似 setUserAga 等逻辑    default:      return preState;  }};
    // constants.jsexport const SET_USERNAME = 'SET_USERNAME';

    reducer 是一个用于更新状态的函数,接收原来的状态 preState 和一个更新动作对象 action。

    action 对象有一个 表示此次操作的描述 type其他数据属性(通常为 payload)。payload 会以某种方式去计算出一个新的状态,替换掉 redux 中原来的 state。

    { type: 'SET_USERNAME', payload: '新用户名'}

    type 通常是一个字符串,比如我们会用 'COUNT_INCREMENT' 来给一个计数器加一,或用 'SET_USERNAME' 来更新用户名。reducer 会根据不同的 type 来执行不同的更新 state 行为。

    action 的构造我们通常会用一个函数帮忙构建,这种函数称为 Action Creator:

    // user_action.jsimport { SET_USERNAME } from './constants';export const setUsernameAction = (data) => {  return {    type: SET_USERNAME,    payload: data  };};

    有了 reducer,我们可以用它们来构建我们的 store。store 可以访问所有的保存在 redux 状态:

    import { combineReducers, createStore } from 'redux';import { userReducer } from './user_reducer';const store = createStore(  combineReducers({    user: userReducer  }));export default store;

    combineReducers 可以将多个 reducer 组合在一起,有各自对应的属性名。比如上面的代码,我们可以通过 store.getState().user 来拿到用户对象。

    如果你又新增了 counter 状态对象,只需再加上 counter: counterReducer,就可以用 store.getState().counter 来拿到这个对象。

    createStore 用于创建应用中所有的 state,然后这些 state 都会存放到这个被返回的 store 里。

    现在我们的 User 组件就变成这样了:

    import { Component, createRef } from 'react';import store from '../store/store';import { setUsernameAction } from '../store/user_action';class User extends Component {  inputRef = createRef();  componentDidMount() {    store.subscribe(() => {      this.setState({});    });  }  setUsername = () => {    store.dispatch(setUsernameAction(this.inputRef.current.value));  };  render() {    return (      <div>        <div>用户名: {store.getState().user.name}</div>        <input ref={this.inputRef} type="text" />        <button onClick={this.setUsername}>设置用户名</button>      </div>    );  }}export default User;
    • store.getState() 可以拿到 state 对象,通过它,我们获取到其下我们需要的对象,比如 user 对象。

    • store.dispatch(action)  派发 action 对象,触发状态的更新。

    • store.subscribe(fn) 订阅状态的变化,执行回调函数。这里我们一发现状态发生了变化,就立刻重新渲染组件。

    Redux 本质是发布订阅模式,状态集中在一起,状态可以通过 store.getState() 访问,通过 store.dispatch(action) 改变状态,通过 store.subscribe(fn) 订阅状态变化(React 组件监听到变化后,重新渲染组件)。

    这种写法是最原始的写法,可以用在任何框架中。

    缺点很明显:用到 redux 的组件要订阅 state 变化,一变化就重新渲染组件。有时候其他组件的 state 变化了,当前组件也会进行不必要的重新渲染

    自己去判断吧,又太繁琐,容易写错,也容易忘记订阅。对于忘记订阅的问题,我们也可以直接把让根组件来监听和重新渲染,但这样性能很差

    接下来西瓜哥要讲的 React-Redux 库可以解决这个问题。它能够在当前组件用到的特定 state 发生改变时,才重新渲染组件。

    React-Redux

    发现大家都很喜欢在 React 里用 Redux,于是 Facebook 出了一个 React-Redux 库,让大家能够更好更正确地在 React 中使用 Redux。

    React-Redux 配合 connect 高阶组件

    我们先看看使用 connect 的写法。

    demo:codesandbox.io/s/react-red&hellip;

    React-Redux 引入了一个容器组件的概念,这个组件专门负责和 redux 打交道 。容器组件其实是一个高阶组件,将真正的 UI 组件做一个封装,在上面做了以下工作:

    • 将 state 和 dispatch 映射到 props,注入到 UI 组件中

    • 监听 state 变化,必要时重新渲染 UI 组件。

    高阶组件:一个函数,它会接收组件参数,然后返回一个新的组件。高阶组件的作用是对真正的 UI 组件做一些复用的逻辑的封装,通常用于做功能增强。

    随着 React Hooks 愈发流行,大家现在更喜欢用 React Hooks 来取代高阶函数,写法更优雅。

    const ContainerComponent = connect(  mapStateToProps,  mapDispatchToProps,)(UIComponent);

    现在开始改造项目。

    我们创建一个 container 文件夹,里面放上 User.jsx 文件,里面写上如下内容:

    // containers/User.jsximport { connect } from 'react-redux';import UserUI from '../components/User';import { setUsernameAction } from '../store/user_action';export default connect(  // mapStateToProps  (state) => ({ user: state.user }),  // mapDispatchToProps  (dispatch) => ({    setUsername: (newName) => dispatch(setUsernameAction(newName))  }))(UserUI);

    然后记得在使用该容器的地方,传入我们的 store 对象,如下:

    import UserContainer from './containers/User';import store from './store/store';import './styles.CSS';export default function App() {  return <UserContainer store={store} />;}

    当然每个容器组件都要传入 store 未免太麻烦,我们通常会使用另一种做法:使用 redux-react 提供的 Context Provider,包裹住根组件,如下:

    import { Provider } from 'react-redux';ReactDOM.render(  <Provider store={store}>    <App />  </Provider>,  document.getElementById('root'));

    然后是 UI 组件的改造:

    import { Component, createRef } from 'react';class User extends Component {  inputRef = createRef();  render() {    return (      <div>        <div>用户名: {this.props.user.name}</div>        <input ref={this.inputRef} type="text" />        <button          onClick={() => this.props.setUsername(this.inputRef.current.value)}        >          设置用户名        </button>      </div>    );  }}export default User;

    UI 组件的 props 会拿到 user 对象、setUsername 方法以及我们注入的 store 对象(如果用 Context 的方式则取不到)。

    React中如何使用Redux

    使用了 connect 后,只有组件用到的 state 改变了,才会触发组件的更新

    这里有个需要特别注意的地方,就是你要 保证新的状态对象和旧状态不相等,这样才能触发组件重新渲染,这在处理对象方法时容易出错。你需要拷贝一个新的对象作为新的状态,推荐使用扩展运算符的写法。

    // user_reducer.js// 错误的写法,新的 state 依旧指向原来的对象preState.name = action.payload;return preState;// 正确的写法return { ...preState, name: action.payload };

    或者可以考虑使用 immer 这种不可变数据结构库。

    React-Rudex 配合 React Hooks

    前面我们用了 connect 这么一个高阶组件,是为了给 UI 组件增强功能。

    说到增强功能,react-redux 也提供了现在非常流行的 React Hooks 写法,写起来更优雅,也是目前西瓜哥我所在公司的做法。

    这里我们就不需要 connect 高阶组件了,也就是说不需要容器组件。

    demo:codesandbox.io/s/react-red&hellip;

    // User.jsimport { useEffect, useRef } from 'react';import { useDispatch, useSelector } from 'react-redux';import { setUsernameAction } from '../store/user_action';const User = () => {  // 获取状态  const user = useSelector((state) => state.user);  // 获取 dipatch 方法  const dipatch = useDispatch();  const inputRef = useRef(null);  return (    <div>      <div>用户名: {user.name}</div>      <input ref={inputRef} type="text" />      <button        onClick={() => {          const newName = inputRef.current.value;          dipatch(setUsernameAction(newName));        }}      >        设置用户名      </button>    </div>  );};export default User;

    通过 useSelector 我们可以拿到通过上下文绑定的 state,然后从中获取我们需要用到的状态

    const user = useSelector((state) => state.user);

    如果有多个,我们可以写成对象的形式:

    const { user, counter } = useSelector((state) => ({  user: state.user,  counter: state.counter}));

    是不是有点像 connect 的 mapStateToProps。

    然后是获取 dispatch 方法:

    const dipatch = useDispatch();

    hook 非常优雅,但我也发现,相比 connect 写法,我们的 redux 状态逻辑和组件耦合在一起了。不过一般我们的组件都是业务组件,还是可以接受的。

    Redux Toolkit

    我们可以看到,我们要维护一个状态,我们要写 reducer 方法、action creator 方法,还要用一个 contants.js 文件集中式管理所有的 actionType 字符串。

    你发现你写了非常多的 模板代码,每加一个 state 就要创建上面这些东西,各个文件里跑来跑去,人都麻了。

    于是 redux 又出了一个工具集库 Redux Toolkit,来解决这个问题。

    demo:codesandbox.io/s/redux-too&hellip;

    Redux Toolkit 提供了 createSlice 方法,可以帮你用更少的代码生成配套的 reducer 和 action,而且有很好的可维护性

    // userSlice.jsimport { createSlice } from '@reduxjs/toolkit';const userSlice = createSlice({  name: 'user',  initialState: {    name: '前端西瓜哥',    age: 88  },  reducers: {    setUsername: (state, action) => {      // 因为 Redux Toolkit 内置使用了 immer,所以可以直接改。      state.name = action.payload;    }  }});// actionsexport const { setUsername } = userSlice.actions;// 获取自己需要的 state,用在组件的 userSeletor hook 上。export const selectUser = (state) => state.user;// reducerexport default userSlice.reducer;

    createSlice 传入 name(标识符,生成 actions 要用到)、initialState(初始值)、reducers(变成了对象形式)参数,然后返回一个对象。

    这个返回的 slice 对象有 actions 对象属性,比如上面的代码,actions 下有一个 setUsername 的方法,执行后会返回 {type: "user/setUsername", payload: "新名字"}

    可以看到 action 的 type 是根据 name 和 reducers 的属性生产的,确保唯一性。

    slice 还有一个 reducer 对象,其实就是将前面传入的 reducers 配合自动生成的 action 转换为了函数的形式。

    createSlice 干了什么事?createSlice 将原来管理一个状态但代码却是分离的 action 和 reducer 集中在了一起,不用自己去起 actionType 的名字

    然后是生成 store 也要改成 configureStore 的写法:

    // store.jsimport { configureStore } from '@reduxjs/toolkit';import userReducer from './userSlice';const store = configureStore({  reducer: {    user: userReducer  }});export default store;

    感谢各位的阅读,以上就是“React中如何使用Redux”的内容了,经过本文的学习后,相信大家对React中如何使用Redux这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

    --结束END--

    本文标题: React中如何使用Redux

    本文链接: https://www.lsjlt.com/news/338680.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    本篇文章演示代码以及资料文档资料下载

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档
    猜你喜欢
    • React项目中使用Redux的 react-redux
      目录背景UI 组件容器组件connect()mapStateToProps()mapDispatchToProps()组件实例:计数器背景 在前面文章一文理解Redux及其工作原理中...
      99+
      2022-11-13
    • React中如何使用Redux
      这篇文章主要讲解了“React中如何使用Redux”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“React中如何使用Redux”吧!Redux 是一种状态容器 JS 库,提供可预测的状态管理...
      99+
      2023-07-02
    • 如何使用react-redux
      本文小编为大家详细介绍“如何使用react-redux”,内容详细,步骤清晰,细节处理妥当,希望这篇“如何使用react-redux”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。...
      99+
      2022-10-19
    • 如何在React中直接使用Redux
      React中使用Redux 开始之前需要强调一下,redux和react没有直接的关系,你完全可以在React, Angular, Ember, jQuery, or vanilla...
      99+
      2022-11-13
      React使用Redux React Redux用法
    • React/Redux应用如何使用Async/Await
      小编给大家分享一下React/Redux应用如何使用Async/Await,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Asyn...
      99+
      2022-10-19
    • redux在react中怎么用
      这篇文章主要介绍redux在react中怎么用,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Redux是一个数据状态管理插件,当使用React或是vue开发组件化的SPA程序时,组件之间共享信息是一个非常大的问题。例...
      99+
      2023-06-15
    • react中redux有什么用
      这篇文章主要介绍了react中redux有什么用,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。环境准备为了方便,这里使用create-rea...
      99+
      2022-10-19
    • 怎么在React项目中使用Redux
      这篇文章主要介绍“怎么在React项目中使用Redux”,在日常操作中,相信很多人在怎么在React项目中使用Redux问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么在R...
      99+
      2022-10-18
    • react-redux及redux状态管理工具使用详解
      目录react-redux使用及原理1、下载 react-redux redux redux-thunk三个依赖包2、配置store对象,用来管理全局状态3、创建reducer.js...
      99+
      2023-01-31
      redux状态管理 react-redux状态管理
    • 如何使用React + Redux + React-router构建可扩展的前端应用
      这篇文章将为大家详细讲解有关如何使用React + Redux + React-router构建可扩展的前端应用,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解...
      99+
      2022-10-19
    • React 中使用 Redux 的 4 种写法小结
      目录不使用 Redux 的写法最底层的写法React-ReduxReact-Redux 配合 connect 高阶组件React-Rudex 配合 React HooksRedux ...
      99+
      2022-11-13
    • React使用redux基础操作详解
      目录一,什么是redux二,安装redux谷歌调试工具三,操作store 改变四,写redux的小技巧一,什么是redux Redux是一个用来管理管理数据状态和UI状态的JavaS...
      99+
      2023-01-13
      React使用redux React redux
    • 一文详解React Redux使用方法
      目录一、理解JavaScript纯函数1.1 纯函数的概念1.2 副作用概念的理解1.3 纯函数在函数式编程的重要性二、Redux的核心思想2.1 为什么需要 Redux2.2 Re...
      99+
      2022-11-13
    • 如何使用Redux Toolkit简化Redux
      目录Redux Toolkit解决的问题它包括什么?Redux Toolkit API的主要功能?createSlice有什么特别之处?处理异步Redux流最后的想法了解Redux ...
      99+
      2022-11-12
    • 在React中使用Redux解决的问题小结
      目录在 React 中使用 Redux 解决的问题在 React 项目中加入 Redux 的好处React + Redux 安装 ReduxReact 中 Redux 的工作流程Re...
      99+
      2022-11-13
      React + Redux 案例 React 使用 Redux
    • 在React-Native中如何持久化redux数据
      这篇文章主要为大家展示了“在React-Native中如何持久化redux数据”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“在React-Native中如何持久...
      99+
      2022-10-19
    • 使用react+redux实现弹出框案例
      本文实例为大家分享了用react+redux实现弹出框案例的具体代码,供大家参考,具体内容如下 redux 实现弹出框案例 1、实现效果,点击显示按钮出现弹出框,点击关闭按钮隐藏弹出...
      99+
      2022-11-13
    • React immer与Redux Toolkit使用教程详解
      目录1. immer1.1 setState结合immer使用1.2 useState结合immer使用1.3 immer和redux集合2. Redux Toolkit1. immer概述:它和immutable相似的,实现了操作对象的数...
      99+
      2022-10-21
    • React Flux与Redux设计及使用原理
      目录1. redux介绍及设计和使用的三大原则2. redux工作流3. redux原理解析4. reducer 扩展5. redux中间件6. Redux DevTools Ext...
      99+
      2023-03-19
      React Flux原理 React Redux原理 React Flux与Redux
    • 如何实现react+redux的升级版todoList
      这篇文章主要为大家展示了“如何实现react+redux的升级版todoList”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“如何实现react+redux的升...
      99+
      2022-10-19
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作