7.react useReducer使用与常见问题

useReducer函数

1. useState的替代方案.接收一个(state, action)=>newState的reducer,
并返回当前的state以及与其配套的dispatch方法

2. 在某些场景下,useReducer会比useState更加适用,例如state逻辑较为复杂,
且**包含多个子值**,或者下一个state依赖于之前的state等

清楚useReducer场景?
与useState区别?
不足之处,只能处理同步
如何实现异步,提供了两个案例?

1. 用useState做登录

一组响应式数据有关联关系,可以做成一个整体,使用useReducer将其作为一个整体实现

<body>
  <div id="app"></div>
  <script type="text/babel">
    let app = document.querySelector('#app');
    let root = ReactDOM.createRoot(app);
    let { useState } = React;

    // 用useState做登录
    // >  一组响应式数据有关联关系,可以做成一个整体,使用useReducer将其作为一个整体实现
    let Welcome = (props) => {  
      const [ isLogin, setLogin ] = useState(true);
      const [ isLogout, setLogout ] = useState(false);
      const handleLogin= () => {
        setLogin(true);
        setLogout(false);
      }

      const handleLogout= () => {
        setLogout(true);
        setLogin(false);
      }
      return (
        <div>
         {
          isLogin?
          <button onClick={handleLogout}>登出</button>:
          <button onClick={handleLogin}>登录</button>
         }
        </div>
      );
    }
    
    let element = (
      <Welcome />
    );
    root.render(element);
  </script>
</body>

2. 改为useReducer

<body>
  <div id="app"></div>
  <script type="text/babel">
    /* 
    useReducer改写
    */

    let app = document.querySelector('#app');
    let root = ReactDOM.createRoot(app);
    let { useReducer } = React;


    let loginState = {
      isLogin: true,
      isLogout: false
    }

    // 不足: 处理同步action
    let loginReducer = (state, action) => {
      switch (action.type) {
        case 'login':
          return { isLogin: true, isLogout: false }
        case 'logout':
          return { isLogin: false, isLogout: true }
        default:
          throw new Error()
      }
    }
    // 用useReducer做登录
    // > 根据类型,决定不同的state处理变化
    let Welcome = (props) => {
      const [state, loginDispatch] = useReducer(loginReducer, loginState);
      const handleLogin = () => {
        loginDispatch({ type: 'login' })
      }

      const handleLogout = () => {
        loginDispatch({ type: 'logout' })
        // loginDispatch({ type: 'logout' ,payload:''})
      }
      return (
        <div>
          {
            state.isLogin ?
              <button onClick={handleLogout}>登出</button> :
              <button onClick={handleLogin}>登录</button>
          }
        </div>
      );
    }

    let element = (
      <Welcome />
    );
    root.render(element);
  </script>
</body>

不足

useReduer只处理同步请求,对异步请求如何处理?
https://zhuanlan.zhihu.com/p/114367502
在这里插入图片描述

在这里插入图片描述

3.1 异步封装

组件页面
const init = { dataList:[] };//初始化dataState
 
const [state,dispatch] = useReducer(reducer,init);
 
useEffect(() => {
    //发送网络请求
    axios.get("/user?ID=123").then(res => {
        dispatch({
            type:ACTION_TYPE.GETDATA,
            payload:res.data //后端返回的数据
        })
    })
},[]);
 
//使用 state.dataList 渲染页面
在reducer页面

function reducer(state,action){
    switch(action.type){
        case "getData":
            return { //根据需求对数据做出操作,这里将返回的数据与初始化的数据合并
                ...state,
                dataList:action.payload 
            };
}    
 
export default reducer;

3.2 异步封装

初始化直接执行获取数据

import React, { useEffect, useState, useReducer } from "react";
import ReactDom from "react-dom";
import $ from "jquery";

const useProduct = () => {
  const [data, dispatch] = useReducer((state, action) => {
    switch (action.type) {
      case "a":
        return action.value;
      default:
        return [];
    }
  }, []);

  useEffect(() => {
    $.ajax({
      url: "http://suggest.taobao.com/sug?code=utf-8&q=袜子",
      dataType: "jsonp",
      jsonp: "callback",
      success: (data) => {
        dispatch({
          type: 'a',
          value: data.result
        });
      },
      error: data => dispatch({type: 'error', msg: data})
    });
  }, []);

  return data;
};

const Index = () => {
  const data = useProduct();

  return <>{data.length}</>;
};

ReactDom.render(<Index />, document.getElementById("root"));

官网:
1. https://zh-hans.legacy.reactjs.org/docs/hooks-reference.html#usereducer

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

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

相关文章

部署你自己的导航站-dashy

现在每天要访问的网页都太多了&#xff0c;尽管chrome非常好用&#xff0c;有强大的标签系统。但是总觉的少了点什么。 今天我就来分享一个开源的导航网站系统 dashy。这是一个国外的大佬的开源项目 github地址如下&#xff1a;https://github.com/Lissy93/dashy 来简单说一下…

git操作:将一个仓库的分支提交到另外一个仓库分支

这个操作&#xff0c;一般是同步不同网站的同个仓库&#xff0c;比如说gitee 和github。某个网站更新了&#xff0c;你想同步他的分支过来。然后基于分支开发或者其它。 操作步骤 1.本地先clone 你自己的仓库。也就是要push 分支的仓库。比如A仓库&#xff0c;把B仓库分支&am…

函数(个人学习笔记黑马学习)

1、函数定义 #include <iostream> using namespace std;int add(int num1, int num2) {int sum num1 num2;return sum; }int main() {system("pause");return 0; } 2、函数的调用 #include <iostream> using namespace std;int add(int num1, int num2…

2023-8-31 Dijkstra求最短路(二)

题目链接&#xff1a;Dijkstra求最短路 II #include <iostream> #include <cstring> #include <algorithm> #include <vector> #include <queue>using namespace std;typedef pair<int, int> PII;const int N 150010;int n, m; int h[N…

网络中的问题2

距离-向量算法的具体实现 每个routerY的路由表表项 involve<目的网络N&#xff0c;距离d&#xff0c;下一跳X> 对邻居X发来的报文,先把下一跳改为X,再把距离1,if original route table doesn’t involve N,add this item&#xff1b; else if original table’s relate…

Mysql 索引

索引 索引是一个排序的列表&#xff0c;在这个列表中存储着索引的值和包含这个值的数据所在行的物理地址&#xff08;类似于C语言的链表通过指针指向数据记录的内存地址&#xff09; 使用索引后可以不用扫描全表来定位某行的数据&#xff0c;而是先通过索引表找到该行数据对应…

mongodb 分片集群部署

文章目录 mongodb 分片部署二进制安装三台config 配置shard 分片安装shard1 安装shard2 安装shard3 安装mongos 安装数据库、集合启用分片创建集群认证文件创建集群用户部署常见问题 mongodb 分片部署 二进制安装 mkdir -p /data/mongodb tar xvf mongodb-linux-x86_64-rhel7…

Python编程——深入了解不可变的元组

作者&#xff1a;Insist-- 个人主页&#xff1a;insist--个人主页 本文专栏&#xff1a;Python专栏 专栏介绍&#xff1a;本专栏为免费专栏&#xff0c;并且会持续更新python基础知识&#xff0c;欢迎各位订阅关注。 目录 一、元组是什么 二、元组的定义 1、相同类型组成元组…

[C++]构造与毁灭:深入探讨C++中四种构造函数与析构函数

个人主页&#xff1a;北海 &#x1f390;CSDN新晋作者 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏✨收录专栏&#xff1a;C/C&#x1f91d;希望作者的文章能对你有所帮助&#xff0c;有不足的地方请在评论区留言指正&#xff0c;大家一起学习交流&#xff01;&#x1f9…

05架构管理之持续集成-DevOps的理解与实现

专栏说明&#xff1a;针对于企业的架构管理岗位&#xff0c;分享架构管理岗位的职责&#xff0c;工作内容&#xff0c;指导架构师如何完成架构管理工作&#xff0c;完成架构师到架构管理者的转变。计划以10篇博客阐述清楚架构管理工作&#xff0c;专栏名称&#xff1a;架构管理…

分享一个vue-slot插槽使用场景

需求再现 <el-table-column align"center" label"状态" prop"mitStatus" show-overflow-tooltip />在这里&#xff0c;我想对于状态进行一个三目判断&#xff0c;如果为0那就是进行中&#xff0c;否则就是已完成&#xff0c;期初我是这样写…

项目-IM

zk 启动类实现CommandLineRunner接口&#xff0c;重写run()方法 单聊 群聊 离线消息

Android OTA 相关工具(六) 使用 lpmake 打包生成 super.img

我在 《Android 动态分区详解(二) 核心模块和相关工具介绍》 介绍过 lpmake 工具&#xff0c;这款工具用于将多个分区镜像打包生成一个 Android 专用的动态分区镜像&#xff0c;一般称为 super.img。Android 编译时&#xff0c;系统会自动调用 lpmake 并传入相关参数来生成 sup…

uniapp实现:点击拨打电话,弹出电话号码列表,可以选择其中一个进行拨打

一、实现效果&#xff1a; 二、代码实现&#xff1a; 在uni-app中&#xff0c;使用uni.showActionSheet方法实现点击拨打电话的功能&#xff0c;并弹出相关的电话列表供用户选择。 当用户选择了其中一个电话后&#xff0c;会触发success回调函数&#xff0c;并通过res.tapInde…

ELK日志收集系统

目录 一、概述 二、组件 一、logstash 一、工作过程 二、INPUT 三、FILETER 四、OUTPUTS 二、elasticsearch 三、kibana 三、架构类型 一、ELK 二、ELKK 三、ELFK 四、ELFKK 五、EFK 四、配置ELK日志收集系统集群实验的步骤文档 五、配置ELK日志收集系统集群 …

0201hdfs集群部署-hadoop-大数据学习

文章目录 1 前言2 集群规划3 hadoop安装包上传与安装3.1 上传解压 4 hadoop配置5 从节点同步和环境变量配置6 创建用户7 集群启动8 问题集8.1 Invalid URI for NameNode address (check fs.defaultFS): file:/// has no authority. 结语 1 前言 下面我们配置下单namenode节点h…

地下管线三维自动建模软件MagicPipe3D V3.0发布

2023年9月1日经纬管网建模系统MagicPipe3D V3.0正式发布&#xff0c;该版本经过众多用户应用和反馈&#xff0c;在三维地下管网建模效果、效率、适配性方面均有显著提升&#xff01;MagicPipe3D本地离线参数化构建地下管网模型&#xff08;包括管道、接头、附属设施等&#xff…

GPT能否辅助数学学习

GPT4.0的数学能力怎么样&#xff1f;我们使用镜像站进行实验&#xff0c;通过不同水平的数学看看GPT4.0的数学能力得到进步没有。镜像站的地址我们放在了最后&#xff0c;各位读者也可以自行去测试。 笔者在ChatGPT镜像站进行测试&#xff0c;我们的实验是让GPT4.0自行出数学题…

[javaWeb]Socket网络编程

网络编程&#xff1a;写一个应用程序,让这个程序可以使用网络通信。这里就需要调用传输层提供的 api。 Socket套接字 传输层提供协议&#xff0c;主要是两个: UDP和TCP 提供了两套不同的 api&#xff0c;这api也叫做socket api。 UDP和 TCP 特点对比&#xff1a; UDP: 无连…

【Redis从头学-13】Redis哨兵模式解析以及搭建指南

&#x1f9d1;‍&#x1f4bb;作者名称&#xff1a;DaenCode &#x1f3a4;作者简介&#xff1a;啥技术都喜欢捣鼓捣鼓&#xff0c;喜欢分享技术、经验、生活。 &#x1f60e;人生感悟&#xff1a;尝尽人生百味&#xff0c;方知世间冷暖。 &#x1f4d6;所属专栏&#xff1a;Re…