useState,useEffect使用的几个例子
例子一,需要三次增加的时候可以使用setCount的回调函数获取上次使用的结果
这里三次使用 setCount(count + 1)只能获取一次结果
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
例子二,配合三元表达式展示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直接塞入对象,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;
例子四,购物车价格数量跟随
- 不适合的案例
import { useEffect, useState } from 'react'
import './App.css'
// 不好的示例,这里price不需要通过监听count来实现
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监听的参数,不要监听引用类型,必须监听值类型
这里是因为在JavaScript,两个引用类型指向的不同的引用地址,即使看起来相同也不是全等的
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;
例子六,发送ajax请求时,处理loading数据和初始参数的处理
- useEffect(() => {}, []) 模拟初始化的生命周期
- 这里例子使用 post?.title,当然也可以使用typescript定义数据产生的类型
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中返回一个回调函数可以卸载事件,类似于组件生命周期中销毁的生命周期
- 这里封装了一个公用的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>)
}
例子八 页面计时器
- 页面计时器的错误案例,计时器是跑的,但是由于闭包的锁定,每次count值最终值都是1
// 结果会反复横跳,错误代码
function App() {
const [count, setCount] = useState(0)
useEffect(() => {
setInterval(() => {
console.log("Interval run")
setCount(count + 1)
}, 1000);
}, [])
return (
<div>
{ count }
</div>
)
}
export default App;
- 监听count的值,卸载和加载setInterval
useEffect(() => {
const i = setInterval(() => {
console.log("Interval run")
setCount(count + 1)
}, 1000);
return () => {
clearInterval(i)
}
}, [count])
- 使用set函数的回调,读取上次返回的值
useEffect(() => {
setInterval(() => {
console.log("Interval run")
setCount(prev => prev + 1)
}, 1000);
}, [])
网友评论