自定义hook
hook就是一个函数,有一些特定逻辑的封装函数
- 用于处理字符串(url)
- 数据格式化(日期)
- 业务逻辑性
自定义hook相对于普通js复用逻辑的抽离,然后可以在页面调用
自定义 Hook 是一个函数,主要解决一些状态逻辑重用的问题,其名称以 “use” 开头,其名称以 “use” 开头,函数内部调用其他的 Hooks。
hook是js函数但有两个额外的规则
- 只能在函数最外层调用Hook。不能循环、条件判断或者子函数中调用
- 只能在React的函数组件中调用Hook。不能在其他js函数中调用,但是可以在自定义的hook中
封装两个自定义hooks
- 判断当前的网络情况
import React, { useState, useEffect } from 'react';
// 自定义一个hook 功能判断当前的网络情况
// 函数名要以use开头
// 函数中必须要用到内置hook函数
const useOnline = () => {
const [online, setOnline] = useState(navigator.onLine)
// 让它在第1次挂载时执行
useEffect(() => {
const onlineFn = () => setOnline(true)
const offlineFn = () => setOnline(false)
// js提供的监听事件
window.addEventListener('online', onlineFn, false)
window.addEventListener('offline', offlineFn, false)
return () => {
window.removeEventListener('online', onlineFn, false)
window.removeEventListener('offline', offlineFn, false)
}
}, [])
return online
}
const App = () => {
const online = useOnline()
return (
<div>
{
online
?
<div style={{ color: 'green' }}>在线</div>
:
<div>离线</div>
}
</div>
);
}
export default App;
- 自定义input输入
import React, { useEffect, useState } from 'react';
const useInput = ( defaultValue = "" ) => {
const [value, setvalue] = useState(defaultValue)
return {
value,
onchange: e => setvalue(e.target.value)
}
}
const app = () => {
const username = useInput()
const password = useInput()
return (
<div>
<input type="text" { ...username }/>
<br/>
<input type="text" { ...password }/>
<br/>
<button onClick={ () => {
console.log(username.value, password.value);
} }>
登录
</button>
</div>
)
}
- 自定义网络封装hook
import axios from "axios";
import { useEffect, useState } from "react"
const useRequest = ({uri, method = "GET", data = {} }) => {
const [res, setData] = useState([])
const cb = () => {
return axios({
uri: uri,
method,
data
}).then(res => {
setData([...ret, ...ret.data.data.data])
})
}
useEffect(() => {
cb()
},[]);
}
export default useRequest
以下案例来自React中自定义Hook的使用:
https://blog.csdn.net/weixin_45389051/article/details/107701508
- 自定义context共享
export const UserContext = createContext()
export const TokenContext = createContext()
<UserContext.Provider value={{name:'lvs'}}>
<TokenContext.Provider value={{token:'#ccccc'}}>
<ContextShare/>
</TokenContext.Provider>
</UserContext.Provider>
import React, { useContext } from 'react'
import {UserContext,TokenContext} from '../App'
export default function useUserContext() {
const user = useContext(UserContext)
const token = useContext(TokenContext)
return [user,token]
return (
<div>
</div>
)
}
//将UserContext,TokenContext导入,然后通过useContext来赋值给我们定义的变量,然后给它return出去,这样我们在不同的组件也都能获取到
import React, { useContext } from 'react'
// 使用 Context内的内容
import useUserContext from '../hook/user-hook'
export default function ContextShare() {
const [user,token] = useUserContext()
console.log(user,token)
return (
<div>
</div>
)
}
- 自定义获取页面滚动位置hook
import React,{useState,useEffect} from 'react'
const useScrollPostion = () => {
const [scrollPosition, setScrollPostion] = useState(0)
useEffect(() => {
const handleScroll = () => {
setScrollPostion(window.scrollY)
}
document.addEventListener('scroll', handleScroll);
return () => {
document.removeEventListener('scroll', handleScroll)
}
},[])
return scrollPosition
}
- localstorage存储自定义hook
import React,{ useState, useEffect } from 'react'
export default function useLocalstoagehook(key) {
const [name, setName] = useState(() => {
const name = JSON.parse(localStorage.getItem(key))
return name
})
useEffect(() => {
// localStorage.setItem('name', name)
localStorage.setItem(key, JSON.stringify(name))
}, [name])
return [name,setName]
return (
<div>
</div>
)
}
import React, { useState, useEffect } from 'react'
import useLocalstoagehook from '../hook/localstoagehook'
export default function CustomLocalStorage() {
const [name,setName]= useLocalstoagehook('name')
return (
<div>
{name}
<button onClick={e => setName('lvs')}>设置</button>
</div>
)
}