目錄
- react18之自定義hook ()
- 01:自定義一個 簡單的axios hook 發(fā)起get請求
- useHttp.jsx
- 使用useHttp hook
- 效果
- 02:自定義一個 修改瀏覽器title hook
- 03:自定義一個 localStorage(獲取、存儲、移除) hook
- useLocalStorage.jsx
- 使用hook
- 效果
- 04:自定義一個 useScrollPosition(獲取當前滾動條的位置) hook
- useScrollPosition.jsx
- 使用
- 效果
- 05:自定義一個 useImageToBase64(img轉(zhuǎn)換為base64) hook
-
react18之自定義hook ()
- hook的使用規(guī)則
- 自定義hook本質(zhì)而言就是一個函數(shù),也就是抽離公共部門的代碼,類似抽離組件或者說mixin(vue中的mixin)。
- hook必須以use開頭(不遵循的話,由于無法判斷某個函數(shù)是否包含對其內(nèi)部 Hook 的調(diào)用,React 將無法自動檢查你的 Hook 是否違反了 Hook 的規(guī)則)
- 內(nèi)部正常使用useState useEffect或者其他hooks
- 自定義返回結(jié)果,格式不限
- 在兩個組件中使用相同的 Hook 不會共享 state(自定義 Hook 是一種重用狀態(tài)邏輯的機制(例如設(shè)置為訂閱并存儲當前值),所以每次使用自定義 Hook 時,其中的所有 state 和副作用都是完全隔離的。)
- 每次調(diào)用 Hook,它都會獲取獨立的 state(從 React 的角度來看,我們的組件只是調(diào)用了 useState 和 useEffect,一個組件中可以調(diào)用多次useState和useEffect,它們都是完全獨立的)
01:自定義一個 簡單的axios hook 發(fā)起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數(shù)據(jù) - <button onClick={getName}>getName</button></div><div>設(shè)置name數(shù)據(jù) - <button onClick={setLocalName}>setName</button></div><div>移除name數(shù)據(jù) - <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轉(zhuǎn)換為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>)
}
效果
