React Hooks 學習 - 04 自定義Hook、路由鉤子函式
阿新 • • 發佈:2021-05-19
自定義 Hook 函式
自定義 Hook 是標準的封裝和共享邏輯的方式,其實就是邏輯和內建 Hook 的組合,用於將元件邏輯提取到可重用的函式中。
自定義 Hook 是一個函式,其名稱以 use
開頭,函式內部可以呼叫其它的 Hook。
使用自定義 Hook 提取可複用的邏輯,相比 render props 和 高階函式簡單很多。
示例1
初始示例
import { useState, useEffect, useRef} from 'react'
function App() {
const [count, setCount] = useState(0)
const timerId = useRef()
useEffect(() => {
timerId.current = setInterval(() => {
setCount(count => count + 1)
}, 1000)
return () => {
clearInterval(timerId.current)
}
}, [])
return (
<div>
<div>Count 的值:{count}</div>
<div>Count 的平方:{ count * count}</div>
</div>
)
}
export default App
提取元件
import { useState, useEffect, useRef} from 'react'
function Counter() {
const [count, setCount] = useState(0)
const timerId = useRef()
useEffect(() => {
timerId.current = setInterval(() => {
setCount(count => count + 1)
}, 1000)
return () => {
clearInterval(timerId.current)
}
}, [])
return <div>Count 的值:{count}</div>
}
function PowerCounter() {
const [count, setCount] = useState(0)
const timerId = useRef()
useEffect(() => {
timerId.current = setInterval(() => {
setCount(count => count + 1)
}, 1000)
return () => {
clearInterval(timerId.current)
}
}, [])
return <div>Count 的平方:{count * count}</div>
}
function App() {
return (
<div>
<Counter />
<PowerCounter />
</div>
)
}
export default App
使用自定義 Hook 提取重複邏輯
import { useState, useEffect } from 'react'
// 自定義 Hook
function useCounter() {
const [count, setCount] = useState(0)
const timerId = useRef()
useEffect(() => {
timerId.current = setInterval(() => {
setCount(count => count + 1)
}, 1000)
return () => {
clearInterval(timerId.current)
}
}, [])
return count
}
function Counter() {
const count = useCounter()
return <div>Count 的值:{count}</div>
}
function PowerCounter() {
const count = useCounter()
return <div>Count 的平方:{count * count}</div>
}
function App() {
return (
<div>
<Counter />
<PowerCounter />
</div>
)
}
export default App
示例2
在建立表單元素的時候通常都會將元件的狀態和表單元素進行繫結(value 屬性和 onChange事件),以實現資料同步。
每個表單都需要繫結 value 和 onChange,可以把這個公共的邏輯提取到自定義 Hook 中。
import { useState } from 'react'
function useUpdateInput(initialValue) {
const [value, setValue] = useState(initialValue)
return {
value,
onChange: event => setValue(event.target.value)
}
}
function App() {
const usernameInput = useUpdateInput('')
const passwordInput = useUpdateInput('')
const submitForm = event => {
event.preventDefault()
console.log(usernameInput.value)
console.log(passwordInput.value)
}
return (
<form onSubmit={submitForm}>
<input type="text" name="username" {...usernameInput} />
<input type="password" name="password" {...passwordInput} />
<input type="submit" />
</form>
)
}
export default App
路由鉤子函式
當進入某個路由元件的時候,這個元件的 props 屬性會附加幾個物件:
React 路由模組(react-router-dom)提供了4個鉤子函式,用來獲取相關的路由資訊:
- useHistory:獲取 history 物件
- useLocation:獲取 location 物件
- useRouteMatch:獲取 match 物件
- useParams:獲取 match 物件下的 params 物件,即路由引數
示例
import { BrowserRouter as Router, Route, Link } from 'react-router-dom'
import { useHistory, useLocation, useRouteMatch, useParams } from 'react-router-dom'
function Index(props) {
console.log('Index', props)
console.log('history', useHistory())
console.log('location', useLocation())
return <div>首頁</div>
}
function News(props) {
console.log('News', props)
console.log('match', useRouteMatch())
console.log('params', useParams())
return <div>新聞</div>
}
function App() {
return (
<Router>
<div>
<Link to="/index">首頁</Link>
<Link to="/news/100">新聞</Link>
</div>
<div>
<Route path="/index" component={Index} />
<Route path="/news/:id" component={News} />
</div>
</Router>
)
}
export default App