目录
- 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请求
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>
)
}
效果
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>
)
}
效果