美文网首页
React中useState,useEffect使用的几个例子

React中useState,useEffect使用的几个例子

作者: 中华小灰灰 | 来源:发表于2023-09-16 10:20 被阅读0次

    useState,useEffect使用的几个例子

    • 国外react学习视频案例

    例子一,需要三次增加的时候可以使用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;
    
    

    例子四,购物车价格数量跟随

    1. 不适合的案例
    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;
    
    1. 正确使用
    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>)
    }
    

    例子八 页面计时器

    1. 页面计时器的错误案例,计时器是跑的,但是由于闭包的锁定,每次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;
    
    1. 监听count的值,卸载和加载setInterval
      useEffect(() => {
        const i =  setInterval(() => {
          console.log("Interval run")
          setCount(count + 1)
        }, 1000);
        return () => {
          clearInterval(i)
        }
      }, [count])
    
    1. 使用set函数的回调,读取上次返回的值
      useEffect(() => {
        setInterval(() => {
          console.log("Interval run")
          setCount(prev => prev + 1)
        }, 1000);
      }, [])
    

    相关文章

      网友评论

          本文标题:React中useState,useEffect使用的几个例子

          本文链接:https://www.haomeiwen.com/subject/sdnbvdtx.html