# React Hook - useState ###### tags: `Javascript, React` ## Few gotchas need your attention ## 1. 在 class component 內不能操作 基本上 class component 有類似的功能可以操作 ```javascript= App extends React.Component { // 不能在內使用 useState 等 hook } ``` 只能操作在 function component 內 ```javascript= function App() =>{ // 可以使用 useState 等 hook } ``` ## 2. 不用針對 hook 使用判斷 基本上不能對 hook 使用 if/else , switch 等等判斷式會影響其順序 ```javascript= if(true){ useState(); } ``` IDE 以及瀏覽器都會報錯  這樣就沒有問題,因為 hook 們可以照順序執行 ```javascript= function App() =>{ useState(); useState(); useState(); useState(); } ``` ## useState 簡介 1. 會解構出當前的 state 以及一個可以更新 state 的方法 2. 右邊 useState 內的值為 state 初始值 ```javascript= function App() { const [count, setCount] = useState(4) return ( <div className="App"> <button>-</button> <span>{count}</span> <button>+</button> </div> ); } ``` 印出結果就會把初始值印出來瞜  ## preState 介紹 這邊會是正常的讓加減符號正常運作,運用到 preState 帶入目前的 state 值做運算 ```javascript= function App() { const [count, setCount] = useState(4) function decrementCount(){ setCount(preCount => preCount -1); } function incrementCount(){ setCount(preCount => preCount +1); } return ( <div className="App"> <button onClick={decrementCount}>-</button> <span>{count}</span> <button onClick={incrementCount}>+</button> </div> ); } ``` 但是如果情況是這樣會讓點擊減號時數字會因為觸發兩次而減二,會追蹤現況作者比較推薦這樣寫 ```javascript= function decrementCount(){ setCount(preCount => preCount -1); setCount(preCount => preCount -1); } ``` 但是如果我們使用了,卻只會減一而已,因為第二次的 setCount 內部的 count 還未更新,所以依舊是初始值所以只是取代掉了前面的而已,因此不推薦這樣寫 ```javascript= function decrementCount(){ setCount(count -1); setCount(count -1); } ``` ## 當初始值很複雜很吃效能時,可以這樣處理 運用下方的寫法就可以讓初始值就只會跑一次,就不會每次更新 state 就再跑一次浪費效能 ```javascript= const [count, setCount] = useState(() =>{ // put your code here console.log('function run') return 4 }) ``` 點擊更新 state 時,都不會再次觸發(這邊我點到八都沒觸發)  ### 對照組 這邊就是每次都會觸發函式的對照 ```javascript= function countInitial(){ console.log('function run') return 4 } function App() { // 這樣就會在每次點擊按鈕加減時觸發 re-render 並且每次都會觸發這個函式 const [count, setCount] = useState(countInitial()) } ``` 他每次都會更跑一次初始值的函式浪費效能  ## 面對物件時 FC 的操作 假設情況我們想要在我們要操作的的數字旁邊加一個主題 ```javascript= function App() { const [state, setState] = useState({count:4, theme:'Blue'}) const count = state.count; const theme = state.theme; function decrementCount(){ setState(prevState =>{ return {count: prevState.count - 1} }) }; function incrementCount(){ setCount(preCount => preCount +1); } return ( <div className="App"> <button onClick={decrementCount}>-</button> <span>{count}</span> <button onClick={incrementCount}>+</button> </div> ); } ``` 理想的狀況是我在按下減號之後會出現 3Blue  但卻變成這樣  從範例可以看出物件的部分它並沒有把更新後的 count state merge 進去原本的物件,而是直接取代原本的 state,所以這邊 theme 直接被取代消失了 所以如果你還是想要使用原本的物件內容的話必須這樣操作: 用展開運算子複製原本的 state 並且在後面更新 count 的內容就可以保留物件完整內容摟 ```javascript= function decrementCount(){ setState(prevState =>{ return {...prevState, count: prevState.count - 1} }) }; ``` 然而,比較推薦的寫法會是使用多個 state hook 來取代這種物件的寫法會更方便管理 ```javascript= const [count, setCount] = useState() const [theme, setTheme] = useState() ```
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up