讀者進入以下網址:https://codesandbox.io/s/new,就能進到由 CodeSandbox 提供的線上開發環境以及使用 create-react-app 指令建立好的 React 專案來進行練習
元件除了可以從父元件取得資料之外,也可以擁有自己內部的資料,就是所謂的 state,也可以稱做是元件的狀態,
我們可以建立多個狀態,每一個狀態都有各自的一個函式來更新狀態,一旦狀態被對應的函式更新,就會觸發擁有該狀態的元件重新執行得以更新畫面。
建立狀態的方式如下:
const [狀態名稱, 更新狀態的函式名稱] = React.useState(狀態的初始值);
以下程式碼為例:
function App() {
const [number, setNumber] = React.useState(0);
return (
<div>
<p>{number} 個人說讚</p>
認同請按讚加分享 <button onClick={() => setNumber(number + 1)}>讚</button>
</div>
);
}
呼叫更新狀態的函式不一定會觸發元件重新執行,取決於目前的 state 和新的 state 它們的值。React 使用 ES6 的 Object.is 來判斷目前的 state 和新的 state 是否相等,如果不相等就會觸發元件重新執行,如果相等則不觸發。
一般情況下,我們呼叫 useState 時會直接傳入 state 的初始值,其實我們也可以傳一個會回傳初始值的函式。
例如以下兩種寫法是等價的:
const [number, setNumber] = React.useState(1 + 2 + 3);
const [number, setNumber] = React.useState(() => 1 + 2 + 3);
呼叫「更新狀態的函式」傳入的新的 state 若取決於目前的 state,則我們應該傳入一個會回傳新的 state 的函式,此函式有一個參數為目前的 state,避免產生不如預期的新狀態。
例如以下程式碼:
function App() {
const [number, setNumber] = React.useState(0);
return (
<div>
<p>{number}</p>
認同請按讚加分享 <button onClick={() => {
setNumber(number + 1);
setNumber(number + 1);
setNumber(number + 1);
}}>讚</button>
</div>
);
}
呼叫三次 setNumber(number + 1)
並不會將原本的 number 加三,一樣只會加一而已。應該改為:
function App() {
const [number, setNumber] = React.useState(0);
return (
<div>
<p>{number}</p>
認同請按讚加分享 <button onClick={() => {
setNumber(prevNumber => prevNumber + 1);
setNumber(prevNumber => prevNumber + 1);
setNumber(prevNumber => prevNumber + 1);
}}>讚</button>
</div>
);
}