Web学习笔记-React(Redux)

这篇具有很好参考价值的文章主要介绍了Web学习笔记-React(Redux)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

笔记内容转载自 AcWing 的 Web 应用课讲义,课程链接:AcWing Web 应用课。

之前我们提到过一个问题,就是如果两个兄弟组件要访问对方的数据,需要将数据存放到最近公共祖先上,这样当 DOM 树很复杂时就很麻烦。Redux 就是在整个 DOM 树之外拿出一个地方,用来存储一些全局的值。

1. Redux基本概念

Redux 会将 state 维护成一个树结构,每个节点存一个值,使用一个函数 reducer 维护每个值。Redux 用字典存储子节点,一般被称为 store

我们如果想修改树里面的某一个值,会将整个树重新计算一遍。我们会使用 dispatch 函数,他会递归调用每个 reducer 函数。此外还需要传入一个对象参数,表示需要对哪个节点进行操作,其中有个属性 type,我们会给每个节点定义一个唯一的 type

Redux 的基本概念总结如下:

  • store:存储树结构。
  • state:维护的数据,一般维护成树的结构。
  • reducer:对 state 进行更新的函数,每个 state 绑定一个 reducer。传入两个参数:当前 stateaction,返回新 state
  • action:一个普通对象,存储 reducer 的传入参数,一般描述对 state 的更新类型,其中的 type 属性表示要修改的节点。
  • dispatch:传入一个参数 action,对整棵 state 树操作一遍,即递归调用整棵树的所有 reducer 函数。

我们先创建一个 Redux 项目 redux-app

create-react-app redux-app

进入项目根目录,安装相关的模块:

npm i redux react-redux @reduxjs/toolkit

假设现在我们只维护一个 state,我们构建一个最简单的朴素版 Redux(和 React 无关):

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { configureStore } from '@reduxjs/toolkit';

const f1 = (state = 0, action) => {  // reducer函数
  switch(action.type) {
    case 'add':
      return state + action.val;
    case 'sub':
      return state - action.val;
    default:
      return state;
  }
};

const store = configureStore({  // 将f1函数构建成一棵状态树
  reducer: f1
});

store.subscribe(() => {console.log(store.getState())});  // 每次dispatch完之后会执行一遍该函数

store.dispatch({type: 'add', val: 2});  // 修改state
store.dispatch({type: 'add', val: 3});

console.log(store.getState());  // 返回整棵树的值

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
  </React.StrictMode>
);

现在来看看如何维护两个节点:

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { configureStore } from '@reduxjs/toolkit';

const f1 = (state = 0, action) => {  // reducer函数
  switch(action.type) {
    case 'add':
      return state + action.val;
    case 'sub':
      return state - action.val;
    default:
      return state;
  }
};

const f2 = (state = '', action) => {
  switch(action.type) {
    case 'concat':
      return state + action.character;
    default:
      return state;
  }
};

const f_all = (state = {}, action) => {  // 组合了f1与f2
  return {
    f1: f1(state.f1, action),
    f2: f2(state.f2, action),
  }
};

const store = configureStore({  // 将f_all函数构建成一棵状态树
  reducer: f_all
});

store.subscribe(() => {console.log(store.getState())});  // 每次dispatch完之后会执行一遍该函数

store.dispatch({type: 'add', val: 2});  // 修改f1的state
store.dispatch({type: 'add', val: 3});
store.dispatch({type: 'concat', character: 'abc'});  // 修改f2的state

console.log(store.getState());  // 返回整棵树的值

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
  </React.StrictMode>
);

控制台输出如下:

{f1: 2, f2: ''}
{f1: 5, f2: ''}
{f1: 5, f2: 'abc'}
{f1: 5, f2: 'abc'}

f_all 也可以不用自己手写实现,可以使用 combineReducers 实现:

import { combineReducers } from '@reduxjs/toolkit';

const f_all = combineReducers({
  f1: f1,
  f2: f2,
});

2. React-Redux基本概念

现在我们来看一下 Redux 如何与 React 组合起来。我们需要用 Provider 将我们的整个项目包含起来。React-Redux基本概念如下:

  • Provider 组件:用来包裹整个项目,其 store 属性用来存储 Redux 的 store 对象。
  • connect(mapStateToProps, mapDispatchToProps) 函数:用来将 store 与组件关联起来,该函数会返回一个函数,返回的函数可以将组件作为输入参数,然后返回一个新的组件,这个新的组件会将 state 的值绑定到组件的 props 属性上。
    • mapStateToProps:每次 store 中的状态更新后调用一次,用来更新组件中的值,即将 storestate 的值绑定到组件的 props 属性上。
    • mapDispatchToProps:组件创建时调用一次,用来将 storedispatch 函数传入组件,即将 dispatch 函数映射到组件的 props 属性上。

为了方便展示,我们定义三个组件:AppNumberstate 从0开始)、Stringstate 从空串开始)。

App 代码如下:

import React, { Component } from 'react';
import Number from './number';
import String from './string';

class App extends Component {
    state = {  }
    render() {
        return (
            <React.Fragment>
                <Number />
                <hr />
                <String />
            </React.Fragment>
        );
    }
}

export default App;

然后我们在 index.js 中实现 React-Redux:

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { configureStore } from '@reduxjs/toolkit';
import { combineReducers } from '@reduxjs/toolkit';
import { Provider } from 'react-redux';
import App from './components/app';

const f1 = (state = 0, action) => {  // reducer函数
  switch(action.type) {
    case 'add':
      return state + action.val;
    case 'sub':
      return state - action.val;
    default:
      return state;
  }
};

const f2 = (state = '', action) => {
  switch(action.type) {
    case 'concat':
      return state + action.character;
    default:
      return state;
  }
};

const f_all = combineReducers({
  number: f1,
  string: f2,
});

const store = configureStore({  // 将f_all函数构建成一棵状态树
  reducer: f_all
});

store.subscribe(() => {console.log(store.getState())});  // 每次dispatch完之后会执行一遍该函数

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <Provider store={store}>
    <App />
  </Provider>
);

现在我们来看一下如何在 NumberString 组件中调用他们的 state 值,需要用到一个 API:connect,以 Number 为例:

import React, { Component } from 'react';
import { connect } from 'react-redux';

class Number extends Component {
    state = {  }
    render() {
        console.log(this.props);
        return (
            <React.Fragment>
                <h3>Number: {this.props.number}</h3>
            </React.Fragment>
        );
    }
};

const mapStateToProps = (state, props) => {  // 第一个参数state包含整个状态树的树结构
    return {
        number: state.number,
    }
};

export default connect(mapStateToProps)(Number);

现在我们再来看一下如何修改 state 的值,需要定义 mapDispatchToProps 对象将 dispatch 映射到 props 里,假设我们要在 Number 中操作 String 里的 state文章来源地址https://www.toymoban.com/news/detail-707831.html

import React, { Component } from 'react';
import { connect } from 'react-redux';

class Number extends Component {
    state = {  }

    handleClick = () => {
        this.props.concat('abc');
    }

    render() {
        console.log(this.props);
        return (
            <React.Fragment>
                <h3>Number: {this.props.number}</h3>
                <button onClick={this.handleClick}>添加</button>
            </React.Fragment>
        );
    }
};

const mapStateToProps = (state, props) => {  // 第一个参数state包含整个状态树的树结构
    return {
        number: state.number,
    }
};

const mapDispatchToProps = {
    concat: (character) => {
        return {  // 会返回一个对象,这个对象就是dispatch中用到的action,会将返回值作用到整个状态树中
            type: 'concat',
            character: character,
        }
    }
}

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

到了这里,关于Web学习笔记-React(Redux)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • [尚硅谷React笔记]——第7章 redux

    目录: redux简介 redux工作流程 求和案例_纯react版 求和案例_redux精简版 redux完整版 异步action版 对react-redux的理解 连接容器组件与UI组件,react-redux基本使用 优化1_简写mapDispatch 优化2_Provider组件的使用 优化3_整合UI组件与容器组件 数据共享_编写Person组件,编写Person组件的reduc

    2024年02月06日
    浏览(36)
  • 【前端知识】React 基础巩固(三十二)——Redux的三大原则、使用流程及实践

    单一数据源 整个应用程序的state被存储在一颗object tree 中,并且这个object tree 只存储在一个store中; Redux并没有强制让我们不能创建多个Store,但是那样做不利于数据维护; 单一的数据源可以让整个应用程序的state变得方便维护、追踪、修改; State是只读的 唯一修改State的方法

    2024年02月15日
    浏览(62)
  • 【前端知识】React 基础巩固(三十一)——store数据的订阅和Redux的优化

    store/index.js test.js redux代码优化: 将派发的action生成过程放到一个actionCreators函数中 将定义的所有actionCreators的函数,放到一个独立的文件中:actionCreators.js actionCreators 和 reducer 函数中使用字符串常量是一致的,所以将常量抽取到一个独立的constants.js文件中 将reducer和默认值(

    2024年02月15日
    浏览(50)
  • Web学习笔记-React(路由)

    笔记内容转载自 AcWing 的 Web 应用课讲义,课程链接:AcWing Web 应用课。 本节内容是如何将页面和 URL 一一对应起来。 Web 页面可以分为两大类: 静态页面:页面里的数据是写死的,即整个文件存放在服务器上,当用户访问 URL 时,服务器原封不动地将页面信息传给前端。 动态

    2024年02月09日
    浏览(39)
  • web3 React dapp中编写balance组件从redux取出并展示用户资产

    好啊 上文WEB3 在 React搭建的Dapp中通过redux全局获取并存储用户ETH与自定义token与交易所存储数量中 我们拿到了用户的一个本身 和 交易所token数量 并放进了redux中做了一个全局管理 然后 我们继续 先 起来ganache的一个模拟环境 然后 我们启动自己的项目 顺手发布一下合约 然后

    2024年02月05日
    浏览(39)
  • React中使用Redux (二) - 通过react-redux库连接React和Redux

    react-redux库使用Redux 上一篇文章演示React中直接使用Redux的使用过程是十分繁琐的, 并且有许多重复代码 但是实际上redux官方帮助我们提供了 react-redux 的库,这个库是帮助我们完成连接redux和react的辅助工具, 可以直接在项目中使用,并且实现的逻辑会更加的严谨和高效 这篇我们

    2024年02月20日
    浏览(53)
  • 【React】redux和React-redux

    🎀个人主页:努力学习前端知识的小羊 感谢你们的支持:收藏🎄 点赞🍬 加关注🪐 redux 适用于多交互、多数据源的场景。 使用redux的场景: 某个组件的状态需要共享 一个组件需要改变其他组件的状态时 一个组件需要改变全局的状态时 redux的三大原则: 整个应用的 state

    2024年02月06日
    浏览(57)
  • web3 React dapp项目通过事件从区块链中拿到 已取消 已完成 和所有的订单数据 并存入redux中

    好 上文web3通过antd 在React dapp中构建订单组件基本结构我们算是把一个基本的订单组件展示做出来了 然后 我们继续 起一下环境先 ganache 终端运行 MetaMask 登录一下 然后 打开项目 发布一下合约 然后 运行一下 测试脚本 转入交易所 ETH和grToken 还创建两个订单 然后 运行起 dapp项

    2024年02月05日
    浏览(50)
  • React学习笔记(番外一)——video.js视频播放组件的入门及排坑经历

    很久没有静下心写博客了。近段时间接到一个任务,前端页面要加上视频播放功能。实现加排坑前后花了三天时间(别问我问什么这么久😂),觉得还是有必要记录一下的。 这一部分有必要写在最前面,避免你看了一长串安装、引入、代码,然后发现自己想要播放的视频格

    2024年02月02日
    浏览(47)
  • 【React】React——redux

    🚩🚩🚩 💎个人主页: 阿选不出来 💨💨💨 💎个人简介: 一名大二在校生,学习方向前端,不定时更新自己学习道路上的一些笔记. 💨💨💨 💎目前开发的专栏: JS 🍭Vue🍭React🍭 💨💨💨 Redux 是 JavaScript 状态容器,提供可预测化的状态管理。 redux是什么 redux是一个专门用于

    2024年01月15日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包