keyword
- useRef
- 自定義hooks
useRef
- 有兩個作用,一個是存儲dom,一個是存儲數據
- 存儲dom
// 獲取dom
import React, {useRef,useEffect} from 'react'
export default function RefPage() {
const ref = useRef()
useEffect(() => {
console.log('查看掛載dom的ref:', ref) // 查看掛載dom的ref: {current: button}
})
return (
<div>
<button ref={ref} >我是綁定了ref的button</button>
</div>
)
}
- 存儲數據state/props
// 存儲props值,並用於對比
import React, {useState,useRef,useEffect} from 'react'
// 首次掛載打印 1 4
// 每次修改props上的num後打印 5 3
// 卸載child組件打印 2 5
function Child(props) {
const {num} = props;
let ref = useRef(num)
// 監聽初始化掛載和卸載的副作用
useEffect(() => {
console.log('1',ref)
return () => {
console.log('2')
}
}, [])
// 監聽掛載/更新(利用ref可以區分開是掛載還是更新),和卸載的副作用
useEffect(() => {
if (ref.current !== num) {
console.log('3',ref) // 更新後執行3 {current: 0}
// ⚠️給ref重新賦值
ref.current = num
} else {
console.log('4');
}
return () => {
console.log('5')
}
}, [num])
return (
<div>num: {num}</div>
)
}
export default function RefPage() {
const [show, setShow] = useState(true)
let [num, setNum] = useState(0)
return (
<div>
{
show ? <Child num={num}/> : ''
}
<button onClick={() => {setShow(false)}}>卸載child</button>
<button onClick={() => {setNum(++num)}}>修改props的num</button>
</div>
)
}
自定義hooks
-
Hook 是 React 16.8 的新增特性。它可以讓你在不編寫 class 的情況下使用 state 以及其他的 React 特性
-
hooks使用規則在此重申:1. 必須以use開頭 2. 必須在函數或者hooks內調用,類組件不能使用 3. 必須在頂層使用,不可以放到任何條件or語句內
-
簡單使用
// 自定義一個返回屏幕尺寸的hook - hooks.js
const useClient = function() {
return [{
w: window.innerWidth,
h: window.innerHeight
}]
}
export {useClient}
// 使用 - MyHook.js
import {useClient} from './hooks.js'
export default function MyHook(){
const [client] = useClient();
return (
<div>
<p>w: {client.w}</p>
<p>h: {client.h}</p>
</div>
)
}
- 結合useState使用
// 定義hooks - hooks.js
import {useState} from 'react'
const useScrollY = function(){
const [statey, setStateY] = useState(0);
const scrollY = window.scrollY;
const setScrollY = function(y){
setStateY(y);
window.scrollTo(0, y)
}
return [scrollY, setScrollY]
}
export default {useScrollY}
// 使用 MyHook.js
import {useState} from 'react'
import {useScrollY} from './hooks'
// 製造長列表數據
const arr = [...`.`.repeat(100)]
export default function MyHook(){
const [scrolly, setScrolly] = useScrollY(0)
useEffect(()=>{
// scrolly在隨着滾動而變化
// console.log("scrolly: ", scrolly);
const fn = () => setScrolly(window.scrollY)
window.addEventListener('scroll', fn)
return () => {
window.removeEventListener('scroll', fn)
}
})
return (
<div>
展示初始值{scrolly}
<button onClick={() => {
setScrolly(200)
}}>修改scrollY</button>
<ul>{
arr.map((item, index) => {
return <li key={index}>這是第{item}個</li>
})
}</ul>
</div>
)
}