目录
- 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
-
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请求
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} = propsuseEffect(() => {document.title = titlereturn () => {document.title = 'Original Title';};}, [title])return { title }
}
03:自定义一个 localStorage(获取、存储、移除) hook
useLocalStorage.jsx
import { useState, useEffect } from 'react';const useLocalStorage = (key, initialValue) => {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) : 0setScrollPosition(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>)
}
效果
