日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

React中useState的使用方法及注意事項_React

作者:Ljwen_ ? 更新時間: 2022-10-08 編程語言

一、基本使用

useState是 react 提供的一個定義響應式變量的 hook 函數,基本語法如下:

const [count, setCount] = useState(initialCount)
  • 它返回一個狀態和一個修改狀態的方法,狀態需要通過這個方法來進行修改;
  • initialCount 是我們傳入的一個初始狀態,它是惰性的,我們可以通過傳一個函數來返回一個值當作初始狀態,并且這個函數只會在初始渲染時執行一次;
const [count, setCount] = useState(() => {
    const initialCount = someExpensiveComputation();
    return initialCount
})

接下來把定義好的狀態運用到頁面:

import { useState } from 'react'
function App() {
    const [count, setCount] = useState(0)
    const handleClick = () => {
        setCount(count + 1)
        // 傳入一個函數,更新的值是基于之前的值來執行
        // setCount(count => count + 1)
    }
    return (
    	<div>
        	<h4>count: {count}</h4>
            <button onClick={ handleClick }>點擊更新狀態</button>
        </div>
    )
}

頁面渲染完成后,我們可以看到 count的值是 0,當我們點擊按鈕時,會將 count的值加 1,頁面也同時更新;

了解完基礎用法后,我們可以思考幾個問題;

  • setCount修改值時它是同步還是異步?
  • 連續調用?setCount會發生什么?

第一個問題:setCount修改值時它是同步還是異步?

const handleClick = () => {
    console.log("value1: ", count)
    setCount(count => count + 1)
    console.log("value2: ", count)
}

從圖中我們可以看出,頁面的值是更新了,但是控制臺打印的是之前的值,這是不是也表示 setCount是異步的呢?我們換一種方法,用異步來修改狀態;

const handleClick = () => {
    console.log("value1: ", count)
    setTimeout(() => {
        setCount(count => count + 1)
        console.log("value2: ", count)
    }, 0)
}

顯然,異步修改狀態跟同步修改狀態的結果是一致的,這也表明了 setCount 是異步更新的;那我們要怎么拿到更新后的值呢,我們可以用另外一個 hook 函數 useRef,代碼如下:

function App() {
  const [count, setCount] = useState(0)
  const countRef = useRef(count)
  countRef.current = count
  const handleClick = () => {
    setCount(count => count + 1)
    console.log("value3: ", count)
    setTimeout(() => {
      console.log(countRef.current)
    }, 0)
  }
  return (
    <div>
      <h4>count: {count}</h4>
      <button onClick={handleClick}>點擊更新狀態</button>
    </div>
  )
}

從圖中我們可以看出,我們已經拿到了更新之后的值,useRef不僅可以用于訪問 DOM 節點,也可以用來表示一個容器,current屬性可以保存任何值,而且useRef返回的對象會在整個生命周期內保持;

第二個問題:連續調用 setCount會發生什么?

(1)傳入一個基于狀態的值

const handleClick = () => {
    console.log("value1: ", count)
    setCount(count + 1)
    console.log("value2: ", count)
    setCount(count + 1)
    console.log("value3: ", count)
}

從圖片可以看出,如果我們傳入的是一個普通值,他只會進行最后一次更新;

(2)傳入一個函數

const handleClick = () => {
    console.log("value1: ", count)
    setCount(count => count + 1)
    console.log("value2: ", count)
    setCount(count => count + 1)
    console.log("value3: ", count)
}

可以看出,傳入一個函數的話,它會進行兩次賦值,因為它更新的值是基于之前的值來執行,所以在開發中推薦使用函數傳入的形式進行修改;

二、注意事項

1、復雜變量的修改

對于復雜類型的變量我們修改時需要重新定義,在原來數據的基礎上修改不會引起組件的重新渲染,因為 React 組件的更新機制只進行淺對比,也就是更新某個復雜類型數據時只要它的引用地址沒變,就不會重新渲染組件;舉個例子

function App() {
    const [arr, setArr] = useState([1])
    const pushData = () => {
        arr.push(4)
        setArr(arr)
    }
    return (
        <div>
            <h4>{arr.join("-")}</h4>
            <button onClick={pushData}>點擊添加數組</button>
        </div>
    )
}

上面的代碼在點擊按鈕時,視圖不會發生變化,但是 arr的值是變化了,如果想修改這個數組,需要重新定義一個數組來修改,在原數組上的修改不會引起組件的重新渲染,React 組件的更新機制對只進行淺對比,也就是更新某個復雜類型數據時只要它的引用地址沒變,就不會重新渲染組件;

const pushData = () => {
    setArr([...arr, 4])
}

2、異步操作獲取更新的值

在類組件里面,修改值時異步操作可以拿到更新后的值,但是在函數組件,異步獲取是拿不到更新后的值的,舉個例子對比一下:

類組件

class App extends React.Component {
    constructor() {
        super()
        this.state = {
            count: 0
        }
    }
    handleClick = () => {
        this.setState({
            count: this.state.count + 1
        })
        console.log(this.state.count)
        setTimeout(() => {
            console.log(this.state.count)
        })
    }
    render() {
        return (
            <>
            <h4>count: {this.state.count}</h4>
            <button onClick={this.handleClick}>點擊更新狀態</button>
            </>
        );
    }
}

函數組件

function App() {
    const [count, setCount] = useState(0)
    const handleClick = () => {
        setCount(count => count + 1)
        console.log("value1: ", count)
        setTimeout(() => {
            console.log("value2: ", count)
        })
    }
    return (
        <div>
            <h4>count: {count}</h4>
            <button onClick={handleClick}>點擊更新狀態</button>
        </div>
    )
}

顯然,在函數組件中是不能通過異步來獲取更新的值,我們可以通過 useRef來獲取;

const countRef = useRef(count)
countRef.current = count
const handleClick = () => {
    setCount(count => count + 1)
    console.log("value1: ", countRef.current)
    setTimeout(() => {
        console.log("value2: ", countRef.current)
    })
}

總結

原文鏈接:https://blog.csdn.net/Ljwen_/article/details/125319191

欄目分類
最近更新