redux-devtools谷歌扩展插件的使用示例

目录

1. store.ts

2. reducer.ts

3. ReduxProvider.tsx

4. mapStateToProps.ts

5. mapDispatchToProps.ts

6.  Todo组件(最外层包ReduxProvider

7. Todo组件里面涉及的子组件

1) TodoInput.tsx

2) TodoList.tsx

3) TodoItem.tsx

8. App组件使用Todo组件


1. store.ts

参考网站: GitHub - zalmoxisus/redux-devtools-extension: Redux DevTools extension.

下载谷歌扩展插件的地址: react-redux-devtools: react-devtools-v3react-devtools-v4redux-devtools

import { applyMiddleware, combineReducers, legacy_createStore as createStore } from 'redux';
import { composeWithDevTools } from "redux-devtools-extension";
import thunk from 'redux-thunk';
import { todos, visibilityFilter } from './reduer';

// 使用 redux-devtools
const composeEnhancers = composeWithDevTools({
    // options like actionSanitizer, stateSanitizer
  });
  // 使用 redux-thunk 中间件
  const enhancer = composeEnhancers(applyMiddleware(thunk));
export default createStore(combineReducers({ todos, visibilityFilter }), enhancer);

2. reducer.ts

export const visibilityFilter = (state = 'SHOW_ALL', action) => {
    switch (action.type) {
      // 设置显示类型(所有、完成、未完成)
      case 'SET_VISIBILITY_FILTER':
        return action.filter
  
      // 默认是 SHOW_ALL
      default:
        return state
    }
  }

  // 新增列表数据和改变数组数据
  // 将业务逻辑拆分到一个单独文件中,方便进行状态管理
export interface StateProps {
    id: number;
    text: string;
    isFinished: boolean;
  }
  export interface ActionProps {
    type: string;
    [key: string]: any;
  }
export const todos = (state: StateProps[] | [], action: ActionProps) => {
    console.log(state, action);
    switch (action.type) {
      case "ADD":
        return [...state, action.todo];
      case "CHANGESTATUS":
        return state.map((item) => {
          if (item.id === action.id) {
            return Object.assign({}, item, { isFinished: !item.isFinished });
          }
          return item;
        });
      default:
        return state || [];
    }
  };

3. ReduxProvider.tsx

import React from "react";
import { Provider } from "react-redux";
import store from './store';

const ReduxProvider = (props) => {
  return <Provider store={store}>{props.children}</Provider>;
};

export default  ReduxProvider

4. mapStateToProps.ts

// 不同类型的 todo 列表
const getVisibleTodos = (todos, filter) => {
  switch (filter) {
    case "SHOW_ALL": // 全部显示
      return todos;
    case "SHOW_FINISHED":
      return todos.filter((t) => t.isFinished);
    case "SHOW_NOT_FINISH":
      return todos.filter((t) => !t.isFinished);
    default:
      return todos;
  }
};

const mapStateToProps = (state) => {
  return {
    // 根据完成状态,筛选数据
    todoList: getVisibleTodos(state.todos, state.visibilityFilter),
  };
};

export default mapStateToProps;

5. mapDispatchToProps.ts

import { StateProps } from "./reduer";

const mapDispatchToProps = (dispatch) => {
    const changeTodo = (id: number) => {
      dispatch({ type: "CHANGESTATUS", id });
    };
    // 添加todo
    const addTodo = (todo: StateProps) => {
      dispatch({ type: "ADD", todo });
    };
  
    // 显示已完成的
    const showFinished = () => {
      dispatch({ type: "SET_VISIBILITY_FILTER", filter: 'SHOW_FINISHED' });
    }
    // 显示未完成的
    const showNotFinish = () => {
      dispatch({ type: "SET_VISIBILITY_FILTER", filter: 'SHOW_NOT_FINISH' });
    }
    // 显示全部完成的
    const showAll = () => {
      dispatch({ type: "SET_VISIBILITY_FILTER", filter: 'SHOW_ALL' });
    }
  
  
    return {
      addTodo,
      // 切换完成状态
      changeTodo,
      showFinished,
      showNotFinish,
      showAll,
    };
  };

  export default mapDispatchToProps

6.  Todo组件(最外层包ReduxProvider

import React from "react";
import ReduxProvider from "./ReduxProvider";
import { TodoInput } from "./TodoInput";
import { TodoList } from "./TodoList";

// 父组件
export const Todo = () => {
    return (
        <ReduxProvider>
            <TodoInput />
            <TodoList  />
        </ReduxProvider>
    )
}

7. Todo组件里面涉及的子组件

1) TodoInput.tsx

import React from "react";
import { useState } from "react";
import mapStateToProps from "./mapStateToProps";
import mapDispatchToProps from "./mapDispatchToProps";
import { connect } from "react-redux";

// 子组件
const TodoInput0 = (props) => {
  const [text, setText] = useState("");
  const { addTodo, showAll, showFinished, showNotFinish } = props;
  const handleChangeText = (e: React.ChangeEvent) => {
    setText((e.target as HTMLInputElement).value);
  };
  const handleAddTodo = () => {
    if (!text) return;
    addTodo({
      id: new Date().getTime(),
      text: text,
      isFinished: false,
    });
    setText("");
  };
  return (
    <div className="todo-input">
      <input
        type="text"
        placeholder="请输入代办事项"
        onChange={handleChangeText}
        value={text}
      />
      <button style={{ marginLeft: "10px" }} onClick={handleAddTodo}>
        +添加
      </button>
      <button style={{ marginLeft: "10px" }} onClick={showAll}>
        show all
      </button>
      <button style={{ marginLeft: "10px" }} onClick={showFinished}>
        show finished
      </button>
      <button style={{ marginLeft: "10px" }} onClick={showNotFinish}>
        show not finish
      </button>
    </div>
  );
};

const TodoInput = connect(mapStateToProps, mapDispatchToProps)(TodoInput0);
export { TodoInput };

2) TodoList.tsx

import React from "react";
import { TodoItem } from "./TodoItem";
import _ from "lodash";
import { connect } from "react-redux";
import mapStateToProps from "./mapStateToProps";
import mapDispatchToProps from "./mapDispatchToProps";

const TodoList0 = (props) => {
  const { todoList } = props;

  return (
    <div className="todo-list">
      {_.map(todoList, (item) => (
        <TodoItem key={_.get(item, "id")} todo={item || {}} />
      ))}
    </div>
  );
};

const TodoList = connect(mapStateToProps, mapDispatchToProps)(TodoList0);
export { TodoList };

3) TodoItem.tsx

import React from "react";
import _ from "lodash";
import { connect } from "react-redux";
import mapStateToProps from "./mapStateToProps";
import mapDispatchToProps from "./mapDispatchToProps";

// 孙子组件
const TodoItem0 = (props) => {
  const { todo, changeTodo } = props;
  // 改变事项状态
  const handleChange = () => {
    changeTodo(_.get(todo, "id"));
  };
  return (
    <div className="todo-item">
      <input
        type="checkbox"
        checked={todo.isFinished}
        onChange={handleChange}
      />
      <span
        style={{ textDecoration: todo.isFinished ? "line-through" : "none" }}
      >
        {todo.text}
      </span>
    </div>
  );
};
const TodoItem = connect(mapStateToProps, mapDispatchToProps)(TodoItem0);
export { TodoItem };

8. App组件使用Todo组件

import React from "react";
import { Todo } from "./reduxConnectProvider/Todo";

const App: React.FC = () => {
  return (
    <>
      <Todo />
    </>
  );
};

export default App;

效果示意图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/134301.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

组件的设计原则

目录 插槽的基本概念 基础用法 具名插槽 使用场景 布局控制 嵌套组件 组件的灵活性 高级用法 作用域插槽 总结 前言 Vue 的 slot 是一项强大的特性&#xff0c;用于组件化开发中。它允许父组件向子组件传递内容&#xff0c;使得组件更加灵活和可复用。通过 slot&…

【LeetCode】挑战100天 Day09(热题+面试经典150题)

【LeetCode】挑战100天 Day09&#xff08;热题面试经典150题&#xff09; 一、LeetCode介绍二、LeetCode 热题 HOT 100-112.1 题目2.2 题解 三、面试经典 150 题-113.1 题目3.2 题解 一、LeetCode介绍 LeetCode是一个在线编程网站&#xff0c;提供各种算法和数据结构的题目&…

索尼RSV文件怎么恢复为MP4视频

索尼相机RSV是什么文件&#xff1f; 如果您的相机是索尼SONY A7S3&#xff0c;A7M4&#xff0c;FX3&#xff0c;FX3&#xff0c;FX6&#xff0c;或FX9等&#xff0c;有时录像会产生一个RSV文件&#xff0c;而没有MP4视频文件。RSV其实是MP4的前期文件&#xff0c;经我对RSV文件…

进程线程

从Android3.0开始&#xff0c;系统要求网络访问必须在子线程中进行&#xff0c;否则会抛出异常&#xff0c;这么做是为了避免主线程被阻塞而导致ANR&#xff0c;那么网络访问的操作就必须要放到线程中去执行。 进程 进程是操作系统结构的基础&#xff0c;是程序在一个数据集合…

Day27力扣打卡

打卡记录 情侣牵手&#xff08;并查集&#xff09; 链接 class Solution:def minSwapsCouples(self, row: List[int]) -> int:def find(x: int) -> int:if p[x] ! x:p[x] find(p[x])return p[x]n len(row) >> 1p list(range(n))for i in range(0, len(row), 2…

Windows 11系统cmd终端美化、Vscode终端美化

win11美化cmd终端和vscode的终端 1. 修改终端背景2. oh-my-posh2.1 安装oh-my-posh2.2 安装Clink2.3 Clink配置oh-my-posh2.4 下载和配置Nerd字体2.5 修改美化主题 3. vscode终端美化 电脑默认的终端没有语法高亮这些&#xff0c;运行命令和代码输出字体一样&#xff0c;有时会…

计算机视觉中目标检测的数据预处理

本文涵盖了在解决计算机视觉中的目标检测问题时&#xff0c;对图像数据执行的预处理步骤。 首先&#xff0c;让我们从计算机视觉中为目标检测选择正确的数据开始。在选择计算机视觉中的目标检测最佳图像时&#xff0c;您需要选择那些在训练强大且准确的模型方面提供最大价值的图…

初识-Servlet (第一个 Servlet 程序详解)

Servlet 是什么? Servlet 是一种实现动态页面的技术. 是一组 Tomcat 提供给程序员的 API, 帮助程序员简单高效的开发一个 web app. 静态页面就只是单纯的 html 动态页面则是 html 数据 第一个 Servlet 程序 我们写一个 hello world 预期写一个 Servlet 程序, 部署到 Tomca…

WebRTC简介及使用

文章目录 前言一、WebRTC 简介1、webrtc 是什么2、webrtc 可以做什么3、数据传输需要些什么4、SDP 协议5、STUN6、TURN7、ICE 二、WebRTC 整体框架三、WebRTC 功能模块1、视频相关①、视频采集---video_capture②、视频编解码---video_coding③、视频加密---video_engine_encry…

【ElasticSearch】学习使用DSL和RestClient编写查询语句

文章目录 DSL和RestClient的学习前言1、DSL查询文档1.1 查询分类1.2 全文检索查询1.21 全文检索概述1.2.2 基本使用 1.3 精确查询1.3.1 term查询1.3.2 range查询 1.4 地理坐标查询1.4.1 geo_bounding_box查询1.4.2 geo_distance查询 1.5 复合查询1.5.1 常见相关性算法1.5.2 算分…

ArcGIS进阶:栅格计算器里的Con函数使用方法

本实验操作为水土保持功能重要性评价&#xff1a; 所用到的数据包括&#xff1a;土地利用类型数据&#xff08;矢量&#xff09;、植被覆盖度数据&#xff08;矢量&#xff09;和地形坡度数据&#xff08;栅格&#xff09;。 由于实验数据较少&#xff0c;其思路也较为简单&a…

讯飞录音笔误删除WAV录音文件恢复成功案例

讯飞录音笔删除恢复的难点 难点一&#xff0c;电脑无法识别为普通电脑盘符。这个是厂家系统设计上的问题&#xff0c;本博文不涉及。 难点二&#xff0c;一般恢复后播放有间隙性噪音问题。这个是数据碎片问题&#xff0c;是本博文的关注点。 大多数情况下&#xff0c;讯飞录…

钉钉统计部门个人请假次数go

前言 最近小组需要统计部门各种请假次数&#xff0c;写了一个方法&#xff0c;第一次实战中用到递归函数&#xff0c;简单记录一下。 效果展示 这些数据不需要返回json&#xff0c;这里这样是为了方便测试。可以通过这些数据完成其它的操作。 功能实现 钉钉服务端调试工具A…

【java进阶】集合的三种遍历(迭代器、增强for、Lambda)

目录 一、先谈集合&#xff1a; 二、单列集合的三种遍历方式 迭代器遍历 增强for遍历 Lambda表达式遍历 一、先谈集合&#xff1a; &#x1f525;那我们平常用for循环依赖下标遍历不行嘛&#xff0c;这就与集合的分类有关了。 集合的体系结构&#xff1a; collection是单…

【论文笔记】Denoising Diffusion Probabilistic Models

Pre Knowledge 1.条件概率的一般形式 P ( A , B ) P ( B ∣ A ) P ( A ) P(A,B)P(B|A)P(A) P(A,B)P(B∣A)P(A) P ( A , B , C ) P ( C ∣ B , A ) P ( B , A ) P ( C ∣ B , A ) P ( B ∣ A ) P ( A ) P(A,B,C)P(C|B,A)P(B,A)P(C|B,A)P(B|A)P(A) P(A,B,C)P(C∣B,A)P(B,A)P…

[游戏中的图形学实时渲染技术] Part1 实时阴影技术

原理篇&#xff1a; 常见的渲染方程如下&#xff1a; 在不考虑自发光项与考虑阴影对于着色结果的影响之后可以将方程变化为如下形式&#xff1a; 如果射线在到达光源前击中了其他物体时&#xff0c;就认为这条来自光源的光线对着色点没有贡献。 利用上述渲染方程进行正确的着…

使用MybatisPlus时出现的java.lang.NullPointerException异常~

错误描述如下所示&#xff1a; 错误原因&#xff1a;Junit的导包错误 单元测试的包有如下所示两个 我们应该根据springboot的版本进行选择&#xff0c; 在Spring Boot 2.2.X以后使用import org.junit.jupiter.api.Test Junit5 在Spring Boot 2.2.x之前使用import org.junit.T…

基于SSM的校园二手物品交易平台设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

高防IP是什么?有什么优势?

一.高防IP的概念 高防IP是指高防机房所提供的IP段&#xff0c;一种付费增值服务&#xff0c;主要是针对网络中的DDoS攻击进行保护。用户可以通过配置高防IP&#xff0c;把域名解析到高防IP上&#xff0c;引流攻击流量&#xff0c;确保源站的稳定可靠。 二.高防IP的原理 高防I…

k8s 裸金属集群部署metalLB软负载均衡 —— 筑梦之路

metalLB 官方网站 Repo&#xff1a;https://github.com/metallb/metallb 官网&#xff1a;https://metallb.universe.tf/installation metalLB解决什么问题&#xff1f; MetalLB 是一个用于裸机 Kubernetes 集群的负载均衡器实现&#xff0c;使用标准路由协议。 k8s 并没有为裸…