useState,useEffect使用的幾個(gè)例子
- 國(guó)外react學(xué)習(xí)視頻案例
例子一秸应,需要三次增加的時(shí)候可以使用setCount的回調(diào)函數(shù)獲取上次使用的結(jié)果
這里三次使用 setCount(count + 1)只能獲取一次結(jié)果
import { useState } from 'react'
import './App.css'
function App() {
const [count, setCount] = useState(0)
const handleClick = () => {
// setCount(count + 1)
// setCount(count + 1)
// setCount(count + 1)
setCount((prev) => prev + 1)
setCount((prev) => prev + 1)
setCount((prev) => prev + 1)
}
return (
<>
<button onClick={handleClick}>Click me</button>
<p>{count}</p>
</>
)
}
export default App
例子二虑凛,配合三元表達(dá)式展示UI
function ProductId({ id }) {
const [something, setSomething] = useState(0)
useEffect(() => {}, [something])
// if(!id) {
// return 'no id'
// }
return (
<section>
{!id ? 'no products' : <div>card id: {id}</div>}
</section>
)
}
export default ProductId
例子三,多元素的表單软啼,setState直接塞入對(duì)象桑谍,onChange事件作歸納,減少代碼量
import { useEffect, useState } from 'react'
import './App.css'
function App() {
const [form, setForm] = useState({
name: '',
password: '',
phone: ''
})
const handleChange = (e) => {
setForm((prev) => {
return {
...prev,
[e.target.name]: e.target.value
}
})
console.log(form)
}
return (
<form>
<p>name:</p>
<input type="text" onChange={handleChange} name="name" />
<p>password:</p>
<input type="password" onChange={handleChange} name="password" />
<p>phone:</p>
<input type="number" onChange={handleChange} name="phone" />
</form>
)
}
export default App;
例子四祸挪,購(gòu)物車價(jià)格數(shù)量跟隨
- 不適合的案例
import { useEffect, useState } from 'react'
import './App.css'
// 不好的示例锣披,這里price不需要通過(guò)監(jiān)聽(tīng)count來(lái)實(shí)現(xiàn)
function App() {
const singPrice = 5;
const [count, setCount] = useState(0)
const [price, setPrice] = useState(0)
const handleClick = () => {
setCount(count + 1)
}
useEffect(() => {
setPrice(count * singPrice)
}, [count])
return (
<div>
<button onClick={handleClick}>Add +1</button>
<p>show the price: {price}</p>
</div>
)
}
export default App;
- 正確使用
import { useState } from 'react'
import './App.css'
function App() {
const singPrice = 5;
const [count, setCount] = useState(0)
const price = singPrice * count
const handleClick = () => {
setCount(count + 1)
}
return (
<div>
<button onClick={handleClick}>Add +1</button>
<p>show the price: {price}</p>
</div>
)
}
export default App;
例子五,useEffect監(jiān)聽(tīng)的參數(shù)贿条,不要監(jiān)聽(tīng)引用類型雹仿,必須監(jiān)聽(tīng)值類型
這里是因?yàn)樵贘avaScript,兩個(gè)引用類型指向的不同的引用地址整以,即使看起來(lái)相同也不是全等的
function App() {
const [product, setProduct] = useState({
num: 100,
totalPrice: 1000
})
const handleClick =() => {
setProduct({
num: 100,
totalPrice: 1000
})
}
useEffect(() => {
}, [product.num])
return (
<div>
<button onClick={handleClick}>Add +1</button>
<p>show the price: {product.totalPrice}</p>
</div>
)
}
export default App;
例子六胧辽,發(fā)送ajax請(qǐng)求時(shí),處理loading數(shù)據(jù)和初始參數(shù)的處理
- useEffect(() => {}, []) 模擬初始化的生命周期
- 這里例子使用 post?.title,當(dāng)然也可以使用typescript定義數(shù)據(jù)產(chǎn)生的類型
function App() {
const [post, setPost] = useState(null)
const [isLoad, setIsLoad] = useEffect(false)
useEffect(() => {
fetch("https://dummyjson.com/posts/1")
.then((res) => res.json())
.then((data) => {
setPost(data)
setIsLoad(true)
})
}, [])
return (
<div>
{
!isLoad ? "Loading Page ..." : (
<div>
<p>{post?.title}</p>
<p>{post?.body}</p>
</div>
)
}
</div>
)
}
export default App;
例子七 卸載掛載的組件
- useEffect 的return中返回一個(gè)回調(diào)函數(shù)可以卸載事件公黑,類似于組件生命周期中銷毀的生命周期
- 這里封裝了一個(gè)公用的hooks組件
const useWindowSize = () => {
const [windowSize, setWindowSize] = useState(1920)
useEffect(() => {
const handleWindowSizeChange = () => {
setWindowSize(window.innerWidth)
}
window.addEventListener("resize", handleWindowSizeChange)
return () => {
window.removeEventListener("resize", handleWindowSizeChange)
}
}, [])
return windowSize;
}
function component1() {
const size = useWindowSize()
return (<p>component1 page</p>)
}
function component2() {
const size = useWindowSize()
return (<p>component2 page</p>)
}
例子八 頁(yè)面計(jì)時(shí)器
- 頁(yè)面計(jì)時(shí)器的錯(cuò)誤案例,計(jì)時(shí)器是跑的邑商,但是由于閉包的鎖定,每次count值最終值都是1
// 結(jié)果會(huì)反復(fù)橫跳凡蚜,錯(cuò)誤代碼
function App() {
const [count, setCount] = useState(0)
useEffect(() => {
setInterval(() => {
console.log("Interval run")
setCount(count + 1)
}, 1000);
}, [])
return (
<div>
{ count }
</div>
)
}
export default App;
- 監(jiān)聽(tīng)count的值人断,卸載和加載setInterval
useEffect(() => {
const i = setInterval(() => {
console.log("Interval run")
setCount(count + 1)
}, 1000);
return () => {
clearInterval(i)
}
}, [count])
- 使用set函數(shù)的回調(diào),讀取上次返回的值
useEffect(() => {
setInterval(() => {
console.log("Interval run")
setCount(prev => prev + 1)
}, 1000);
}, [])