深入理解 useState
useState
const [state, setState] = useState(initialState)
返回一個 state,以及更新 state 的函數。
在初始渲染期間,返回的狀態 (state) 與傳入的第一個參數 (initialState) 值相同。
initialState 參數只會在組件的初始渲染中起作用,後續渲染時會被忽略。如果初始 state 需要通過複雜計算獲得,則可以傳入一個函數,在函數中計算並返回初始的 state,此函數只在初始渲染時被調用:
const [state, setState] = useState(() => {
const initialState = []
for (let i = 0; i < 100; i++) {
initialState.push(i)
}
return initialState
})
如果你更新 State Hook 後的 state 與當前的 state 相同時,React 將跳過子組件的渲染並且不會觸發 effect 的執行。(React 使用 Object.is 比較算法 來比較 state。)
function Child () {
useEffect(() => {
console.log('Child')
})
return <div>Child</div>
}
function App() {
const [val, setVal] = useState(1)
const handleClick = (e) => {
setVal(1)
}
return (
<div class>
<div>{val}</div>
<button onClick={handleClick}>點擊</button>
<Child></Child>
</div>
);
}
某些場景下,useReducer
會比 useState
更適用,例如 state 邏輯較複雜且包含多個子值,或者下一個 state 依賴於之前的 state 等。並且,使用 useReducer
還能給那些會觸發深更新的組件做性能優化,因爲你可以向子組件傳遞 dispatch 而不是回調函數 。
function Child (props) {
console.log('重新渲染')
function handleClick () {
props.dispatch({type: 'increment'})
}
return (
<button onClick={handleClick}>按鈕</button>
)
}
Child = React.memo(Child)
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
function handleClick() {
dispatch({type: 'increment'})
}
return (
<div>
<h1 onClick={handleClick}>{state.count}</h1>
<Child dispatch={dispatch} />
</div>
)
}
React 會確保 dispatch 函數的標識是穩定的,並且不會在組件重新渲染時改變。這就是爲什麼可以安全地從 useEffect 或 useCallback 的依賴列表中省略 dispatch。
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
function handleClick() {
dispatch({type: 'increment'})
}
const callback = useCallback(() => {
dispatch({type: 'increment'})
}, [])
return (
<div>
<h1 onClick={handleClick}>{state.count}</h1>
<Child callback={callback} />
</div>
)
}
如果直接從 useReducer 返回操作,則其行爲與 useState 幾乎相同。
function App() {
const [name, setName] = useReducer((_, value) => value, '請輸入');
return (
<div class>
<input value={name} onChange={e => setName(e.target.value)} />
</div>
);
}
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/ckxeUOTIBCdynVUAvPKF6w