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

目录

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

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

js 复制代码
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

js 复制代码
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

js 复制代码
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

js 复制代码
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

js 复制代码
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

js 复制代码
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;

使用

js 复制代码
   const scrollPosition = useScrollPosition()
   console.log('scrollPosition', scrollPosition);

效果

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

useImageToBase64.jsx

js 复制代码
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;

使用

js 复制代码
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>
    )
}

效果

相关推荐
ClareXi3 小时前
react项目通过http调用后端springboot服务最简单示例
spring boot·react.js·http
咔咔库奇14 小时前
react动态路由
前端·react.js·前端框架
yqcoder16 小时前
react 中 FC 模块作用
前端·react.js·前端框架
刘志辉16 小时前
react的创建与书写
前端·react.js·前端框架
奔跑草-19 小时前
【前端】深入浅出的React.js详解
前端·react.js·前端框架
小牛itbull20 小时前
ReactPress:深入解析技术方案设计与源码
javascript·react.js·reactpress
秃头女孩y20 小时前
【React】条件渲染——逻辑与&&运算符
前端·react.js·前端框架
小满zs21 小时前
React第十五章(useEffect)
前端·react.js
破浪前行·吴1 天前
使用@react-three/fiber,@mkkellogg/gaussian-splats-3d加载.splat,.ply,.ksplat文件
前端·react.js·three.js
咔咔库奇1 天前
react之了解jsx
前端·javascript·react.js