自定义hook
2022-11-06 本文已影响0人
未路过
多个组件有相同的逻辑的时候,可以把他抽取到一个独立的hook里面。
自定义hook的本质就是函数代码的抽取,他本身不算是react的特性。
自定义hook的要求是函数的名字必须以use开头
练习1
image.pngimport React, { memo, useEffect, useState } from "react";
function useLogLife(cName) {
useEffect(() => {
console.log(cName + "组件被创建");
return () => {
console.log(cName + "组件被销毁");
};
}, []);
}
const Home = memo(() => {
useLogLife("home");
return <h1>Home Page</h1>;
});
const About = memo(() => {
useLogLife("about");
return <h1>About Page</h1>;
});
const App = memo(() => {
const [isShow, setIsShow] = useState(true);
useLogLife("app");
return (
<div>
{isShow && <Home />}
{isShow && <About />}
<button onClick={(e) => setIsShow(!isShow)}>切换</button>
</div>
);
});
export default App;
/*
home组件被创建
about组件被创建
app组件被创建
*/
练习2
image.pngimport React, { memo } from 'react'
import { useUserToken } from "./hooks"
// User/Token
const Home = memo(() => {
const [user, token] = useUserToken()
return <h1>Home Page: {user.name}-{token}</h1>
})
const About = memo(() => {
const [user, token] = useUserToken()
return <h1>About Page: {user.name}-{token}</h1>
})
const App = memo(() => {
return (
<div>
<h1>App Root Component</h1>
<Home/>
<About/>
</div>
)
})
export default App
import { useContext } from "react"
import { UserContext, TokenContext } from "../context"
function useUserToken() {
const user = useContext(UserContext)
const token = useContext(TokenContext)
return [user, token]
}
export default useUserToken
练习3
监听窗口滚动
import { useState, useEffect } from "react";
function useScrollPosition() {
const [scrollX, setScrollX] = useState(0);
const [scrollY, setScrollY] = useState(0);
useEffect(() => {
function handleScroll() {
// console.log(window.scrollX, window.scrollY)
//window和document的区别是,window发生滚轮事件,会传递给document,所以document也会拿到,
setScrollX(window.scrollX);
setScrollY(window.scrollY);
}
window.addEventListener("scroll", handleScroll);
return () => {
window.removeEventListener("scroll", handleScroll);
};
}, []);
return [scrollX, scrollY];
}
export default useScrollPosition;
import React, { memo } from 'react'
import { useUserToken } from "./hooks"
// User/Token
const Home = memo(() => {
const [user, token] = useUserToken()
return <h1>Home Page: {user.name}-{token}</h1>
})
const About = memo(() => {
const [user, token] = useUserToken()
return <h1>About Page: {user.name}-{token}</h1>
})
const App = memo(() => {
return (
<div>
<h1>App Root Component</h1>
<Home/>
<About/>
</div>
)
})
export default App
练习4
image.pngimport { useEffect } from "react"
import { useState } from "react"
function useLocalStorage(key) {
// 1.从localStorage中获取数据, 并且数据数据创建组件的state
const [data, setData] = useState(() => {
const item = localStorage.getItem(key)
if (!item) return ""
return JSON.parse(item)
})
// 2.监听data改变, 一旦发生改变就存储data最新值
useEffect(() => {
localStorage.setItem(key, JSON.stringify(data))
}, [data])
// 3.将data/setData的操作返回给组件, 让组件可以使用和修改值
return [data, setData]
}
export default useLocalStorage
import React, { memo } from 'react'
import { useEffect } from 'react'
import { useState } from 'react'
import useLocalStorage from './hooks/useLocalStorage'
const App = memo(() => {
// 通过key, 直接从localStorage中获取一个数据
// const [token, setToken] = useState(localStorage.getItem("token"))
// useEffect(() => {
// localStorage.setItem("token", token)
// }, [token])
const [token, setToken] = useLocalStorage("token")
function setTokenHandle() {
setToken("james")
}
// const [avatarUrl, setAvatarUrl] = useState(localStorage.getItem("avatarUrl"))
// useEffect(() => {
// localStorage.setItem("avatarUrl", avatarUrl)
// }, [avatarUrl])
const [avatarUrl, setAvatarUrl] = useLocalStorage("avatarUrl")
function setAvatarUrlHandle() {
setAvatarUrl("http://www.james.com/cba.png")
}
return (
<div className='app'>
<h1>App Root Component: {token}</h1>
<button onClick={setTokenHandle}>设置token</button>
<h1>avatarURL: {avatarUrl}</h1>
<button onClick={setAvatarUrlHandle}>设置新头像地址</button>
</div>
)
})
export default App