react18之08自定义hook (简单的axios-get、修改浏览器title、localStorage、获取滚动条位置、img转换为base64)

news2024/12/22 19:50:12

目录

  • react18之自定义hook ()
    • 01:自定义一个 简单的axios hook 发起get请求
      • useHttp.jsx
      • 使用useHttp hook
      • 效果
    • 02:自定义一个 修改浏览器title hook
    • 03:自定义一个 localStorage(获取、存储、移除) hook
      • useLocalStorage.jsx
      • 使用hook
      • 效果
    • 04:自定义一个 useScrollPosition(获取当前滚动条的位置) hook
      • useScrollPosition.jsx
      • 使用
      • 效果
    • 05:自定义一个 useImageToBase64(img转换为base64) hook
      • useImageToBase64.jsx
      • 使用
      • 效果

react18之自定义hook ()

  • hook的使用规则
    • 自定义hook本质而言就是一个函数,也就是抽离公共部门的代码,类似抽离组件或者说mixin(vue中的mixin)。
    • hook必须以use开头(不遵循的话,由于无法判断某个函数是否包含对其内部 Hook 的调用,React 将无法自动检查你的 Hook 是否违反了 Hook 的规则)
    • 内部正常使用useState useEffect或者其他hooks
    • 自定义返回结果,格式不限
    • 在两个组件中使用相同的 Hook 不会共享 state(自定义 Hook 是一种重用状态逻辑的机制(例如设置为订阅并存储当前值),所以每次使用自定义 Hook 时,其中的所有 state 和副作用都是完全隔离的。)
    • 每次调用 Hook,它都会获取独立的 state(从 React 的角度来看,我们的组件只是调用了 useState 和 useEffect,一个组件中可以调用多次useState和useEffect,它们都是完全独立的)

01:自定义一个 简单的axios hook 发起get请求

  • npm i axios

useHttp.jsx

import { useState, useEffect } from "react";
import axios from "axios";
export default function UseHttp(props) {
  const { url } = props;
  const [loading, setLoading] = useState(false);
  const [data, setData] = useState(null);
  const [error, setError] = useState(null);

  useEffect(() => {
    setLoading(true);
    axios.get(url)
      .then((res) => {
        setData(res);
      })
      .catch((err) => {
        setError(err);
      })
      .finally(() => {
        setLoading(false);
      });
  }, [url]);
  return [loading, data, error];
}

使用useHttp hook

import React, { useState,useEffect } from 'react';
import UseHttp from './useHttp';
export default function Base(props) {
    const [list,setList] = useState([])
    const url = 'http://localhost:9999' + '/list'
    const [loading,data,error] = UseHttp({url})
    useEffect(()=>{
      if ( data && data.status === 200) {
        setList(data.data)
      }
    },[data])

    return (
        <div className='content'>
          {
            loading ? '加载中' : 
            <>
             { error ? <div>error</div> :
              <div>
                {
                  list.map(item=>{
                    return (
                      <div key={item.id}>
                        name-{ item.name};
                        age- { item.age }
                      </div>
                    )
                  })
                }
              </div>}
            </>
          }
        </div>
    )
}

效果

在这里插入图片描述

02:自定义一个 修改浏览器title hook

import { useEffect } from 'react';

export default function useTitle(props) {
    const {title} = props

    useEffect(() => {
        document.title = title
        // 组件卸载时,恢复默认标题
        return () => {
          document.title = 'Original Title';
        };
    }, [title])

    return { title }
}

03:自定义一个 localStorage(获取、存储、移除) hook

useLocalStorage.jsx

import { useState, useEffect } from 'react';

const useLocalStorage = (key, initialValue) => {
  // 根据key获取localStorage的数据,若是有数据则返回,没有则返回初始化设置的值
  const [data, setData] = useState(() => {
    let storageVal = localStorage.getItem(key);
    return (storageVal && storageVal !== 'undefined') ? JSON.parse(storageVal) : initialValue;
  });

  // 若是数据有变化 则存储数据
  useEffect(() => {
    localStorage.setItem(key, JSON.stringify(data));
  }, [key, data]);

  const removeLocalStorage = () => {
    setData(initialValue);
    localStorage.removeItem(key);
  };

  return [data, setData, removeLocalStorage];
};

export default useLocalStorage;

使用hook

import React, { useState, useEffect } from 'react';
import useLocalStorage from './useLocalStorage';
export default function Base(props) {
    const [name,setName,removeLocalStorage]= useLocalStorage('name','')
    function getName(){
      console.log('name',name);
    }
    function setLocalName(){
      setName('我是setName')
    }
    function delLocalName(){
      removeLocalStorage('name')
    }
    return (
        <div className='content'>
          <div>
            <div>name-{name}</div>
            <div>获取name数据 - <button onClick={getName}>getName</button></div>
            <div>设置name数据 - <button onClick={setLocalName}>setName</button></div>
            <div>移除name数据 - <button onClick={delLocalName}>delName</button></div>
          </div>
        </div>
    )
}

效果

在这里插入图片描述

04:自定义一个 useScrollPosition(获取当前滚动条的位置) hook

useScrollPosition.jsx

import { useState, useEffect } from 'react';
function useScrollPosition() {
  const [scrollPosition, setScrollPosition] = useState(0);

  useEffect(() => {
    const handleScroll = () => {
      let scrollY = window.scrollY ? Math.round(window.scrollY) : 0
      setScrollPosition(scrollY);
    }
    document.addEventListener("scroll", handleScroll);

    return () => {
      document.removeEventListener("scroll", handleScroll)
    }
  }, []);

  return scrollPosition;
}

export default useScrollPosition;

使用

   const scrollPosition = useScrollPosition()
   console.log('scrollPosition', scrollPosition);

效果

在这里插入图片描述

05:自定义一个 useImageToBase64(img转换为base64) hook

useImageToBase64.jsx

import React, { useState } from 'react';

const useImageToBase64 = () => {
  const [base64Image, setBase64Image] = useState(null);

  const imageToBase64 = (file) => {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();

      reader.onload = () => {
        resolve(reader.result);
      };

      reader.onerror = (error) => {
        reject(error);
      };

      reader.readAsDataURL(file);
    });
  };

  const handleImageUpload = (event) => {
    const file = event.target.files[0];
    if (file) {
      imageToBase64(file)
        .then((base64) => {
          setBase64Image(base64);
        })
        .catch((error) => {
          console.error('Error converting image to Base64:', error);
        });
    }
  };

  return { base64Image, handleImageUpload };
};

export default useImageToBase64;

使用

import React from 'react';
import useImageToBase64 from "../自定义hook/useImageToBase64 "
export default function Test(props) {
  const { base64Image, handleImageUpload } = useImageToBase64();
  console.log('base64Image',base64Image);
    return (
        <div className='content' style={{marginTop:'40px'}}>
          Test
          <div>
            <input type="file" accept="image/*" onChange={handleImageUpload} />
            {base64Image && <img src={base64Image} alt="Uploaded" />}
          </div>
        </div>
    )
}

效果

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【JVM】 垃圾回收篇——自问自答(1)

Q什么是垃圾&#xff1a; 运行程序中&#xff0c;没用任何指针指向的对象。 Q为什么需要垃圾回收&#xff1f; 内存只分配&#xff0c;不整理回收&#xff0c;迟早会被消耗完。 内存碎片的整理&#xff0c;为新对象腾出空间 没有GC程序无法正常进行。 Q 哪些区域有GC&#…

【C++学习】STL容器——list

目录 一、list的介绍及使用 1.1 list的介绍 1.2 list的使用 1.2.1 list的构造 1.2.2 list iterator的使用 1.2.3 list capacity 1.2.4 list element access 1.2.5 list modifiers 1.2.6 list 迭代器失效 二、list的模拟实现 2.1 模拟实现list 三、list和vector的对比…

On Evaluation of Embodied Navigation Agents 论文阅读

论文信息 题目&#xff1a;On Evaluation of Embodied Navigation Agents 作者&#xff1a;Peter Anderson&#xff0c;Angel Chang 来源&#xff1a;arXiv 时间&#xff1a;2018 Abstract 过去两年&#xff0c;导航方面的创造性工作激增。这种创造性的输出产生了大量有时不…

idea-Invalidate caches选项

Clear file system cache and Local History: 清除 IntelliJ IDEA 缓存和本地历史记录&#xff0c;注意要保存现有的信息 Clear VCS Log caches and indexes: remove the cache and indexes of the VCS Log. 这个选项的意思是清除版本控制系统日志的缓存和索引。VCS Log 是 In…

VBA技术资料MF40:VBA_计数筛选状态的数据行数

【分享成果&#xff0c;随喜正能量】人唯有与喜欢的事物发展关系&#xff0c;不管是人或者是物还是事&#xff0c;包括喜欢自己外表、个性的部分&#xff0c;喜欢自己做的事&#xff0c;喜欢自己的创造&#xff0c;喜欢的风景……才给人带来对自己的认同。在与喜欢的事物互动关…

从小白到数据库达人!Mysql优化让你的社招面试无往不利!

大家好&#xff0c;我是小米&#xff0c;在这个美好的时刻又迎来了我们的技术小窝。今天&#xff0c;我们要聊一聊一个在数据库领域中无比重要的话题 —— Mysql 优化&#xff01;是不是感觉很兴奋呢&#xff1f;废话不多说&#xff0c;让我们直接进入今天的主题。 背景知识 …

Hadoop理论及实践-HDFS的Namenode及Datanode(参考Hadoop官网)

HDFS有什么特点&#xff0c;被设计做什么 Hadoop分布式文件系统(HDFS)被设计成适合运行在通用硬件(commodity hardware)上的分布式文件系统。有一下几个特点&#xff1a; HDFS是一个高度容错性的系统&#xff0c;具有高容错、高可靠性、高扩展性的特点&#xff0c;适合部…

2.两数相加(题解)

两数相加 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外&#xff0c;这两个数都…

数学建模—多元线性回归分析(+lasso回归的操作)

第一部分&#xff1a;回归分析的介绍 定义&#xff1a;回归分析是数据分析中最基础也是最重要的分析工具&#xff0c;绝大多数的数据分析问题&#xff0c;都可以使用回归的思想来解决。回归分析的人数就是&#xff0c;通过研究自变量X和因变量Y的相关关系&#xff0c;尝试去解释…

MongoDB 使用总结

&#x1f353; 简介&#xff1a;java系列技术分享(&#x1f449;持续更新中…&#x1f525;) &#x1f353; 初衷:一起学习、一起进步、坚持不懈 &#x1f353; 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正&#x1f64f; &#x1f353; 希望这篇文章对你有所帮助,欢…

MyCat配置文件schema.xml讲解

1.MyCat配置 1.1 schema标签 如果checkSQLschema配置的为false&#xff0c;那么执行DB01.TB_ORDER时就会报错&#xff0c;必须用use切换逻辑库以后才能进行查询。 sqlMaxLimit如果未指定limit进行查询&#xff0c;列表查询模式默认为100,最多只查询100条。因为用mycat后默认数…

【多线程】synchronized 原理

1. 写在前面 本章节主要介绍 synchronized 的一些内部优化机制&#xff0c;这些机制存在的目的呢就是让 synchronized 这把锁更高效更好用&#xff01; 2. 锁升级/锁膨胀 JVM 将 synchronized 锁分为以下四种状态&#xff1a; 无锁&#xff0c;偏向锁&#xff0c;轻量级锁&…

ENSP软件的基本使用命令(第三十一课)

ENSP软件的基本使用命令(第三十一课) 下面的图片是今天操作的核心基础操作 1 命令行页面 交换机 路由器 PC机 分别展示一下 页面的样子 2 基本命令结构

K8S系列文章 之 容器存储基础 Volume

Volume Volume是容器数据卷。我们经常创建删除一些容器&#xff0c;但有时候需要保留容器中的一些数据&#xff0c;这时候就用到了Volume。它也是容器之间数据共享的技术&#xff0c;可以将容器中产生的数据同步到本地。实际就是把容器中的目录挂载到运行着容器的服务器或个人…

Last-Mile Embodied Visual Navigation 论文阅读

论文阅读 题目&#xff1a;Last-Mile Embodied Visual Navigation 作者&#xff1a;JustinWasserman, Karmesh Yadav 来源&#xff1a;CoRL 时间&#xff1a;2023 代码地址&#xff1a;https://jbwasse2.github.io/portfolio/SLING Abstract 现实的长期任务&#xff08;例如…

Spring Cloud Gateway过滤器GlobalFilter详解

一、过滤器的场景 在springCloud架构中&#xff0c;网关是必不可少的组件&#xff0c;它用于服务路由的转发。对客户端进行屏蔽微服务的具体细节&#xff0c;客户端只需要和网关进行交互。所以网关顾名思义&#xff0c;就是网络的一个关卡。它就是一座城的城门守卫。所以这个守…

10亿数据、查询<10s,论基于OLAP搭建广告系统的正确姿势

更多技术交流、求职机会&#xff0c;欢迎关注字节跳动数据平台微信公众号&#xff0c;回复【1】进入官方交流群 由于流量红利逐渐消退&#xff0c;越来越多的广告企业和从业者开始探索精细化营销的新路径&#xff0c;取代以往的全流量、粗放式的广告轰炸。精细化营销意味着要在…

抓包神器-burp

Burp Suite是一款信息安全从业人员必备的集成型的渗透测试工具&#xff0c;它采用自动测试和半自动测试的方式&#xff0c;包含了 Proxy,Spider,Scanner,Intruder,Repeater,Sequencer,Decoder,Comparer等工具模块。通过拦截HTTP/HTTPS的web数据包&#xff0c;充当浏览器和相关应…

机器学习常用Python库安装

机器学习常用Python库安装 作者日期版本说明Dog Tao2022.06.16V1.0开始建立文档 文章目录 机器学习常用Python库安装Anaconda简介使用镜像源配置 Pip简介镜像源配置 CUDAPytorch安装旧版本 TensorFlowGPU支持说明 DGL简介安装DGLLife RDKitscikit-multilearn Anaconda 简介 …

RocketMQ使用

说明&#xff1a;本文介绍RocketMQ的消费模式&消息类型&#xff0c;RocketMQ的安装参考及简单使用&#xff0c;参考&#xff1a;http://t.csdn.cn/BKFPj 消费模式 RocketMQ与RabbitMQ最大的区别在于&#xff0c;RocketMQ是根据消息的Topic锁定消费者的&#xff0c;Topic属…