目录
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} = 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 ) => {
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>
)
}
效果