useState
經典案例:
import { useState } from 'react';
function Example() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
)
}
此例子中, useState(0)
是最新的 hooks api;
語法:
function useState<S>(initialState: S | (() => S)): [S, Dispatch<SetStateAction<S>>];
其中 state 是他的值, setState 是用來設置值的函數, initialState 是初始值
useState-initialState
該初始值可以接受任何參數,但是記得當他接受為一個函數時,就變成了Lazy initialization
(延遲初始化)
該函數返回值即為initialState,
const [count, setCount] = useState(0);
const [count, setCount] = useState(()=>0);
// 這兩種初始化方式 是相等的,但是在函數為初始值時會被執行一次
const [count, setCount] = useState(()=>{
console.log('這里只會在初始化的時候執行')
// class 中的 constructor 的操作都可以移植到這里
return 0
});
// 當第一次執行完畢后 就和另一句的代碼是相同的效果了
useState-setState
也許很多人 在使用 class 的 setState 時候,會經常使用他的回調函數,
但是這里很遺憾,他只接受新的值,如果想要對應的回調,可以使用useEffect,這個問題等會會提供一個跳轉鏈接
useEffect
語法:
function useEffect(effect: EffectCallback, deps?: DependencyList): void;
經典案例:
useEffect(() => {
console.log('在 dep 改變時觸發,若無 dep 則,每次更新組件都會觸發')
return () => {
console.log('在組件 unmount 時觸發')
};
});
deps 必須是一個數組,但是如果是一個空數組時:
useEffect(() => {
console.log('效果的等於 componentDidMount')
}, [])
即使有 deps ,他在初始化時也會觸發一次
與 setState 形成回調函數:
在useState-setState
中提到, class 中 setState 都是有回調的,而在 hooks 中 通過 useEffect 同樣也可以實現它的效果
關於回調值的探秘:
說起回調值,他能接受很多值,但是我們要搞清楚一點 他到底可以接受什么值,而他的變化的檢測:
首先我們應該清楚, string,number,undefined,null 他的值都是能夠正常檢測的,
問題的關鍵還是在於 object 和 function
關於 object 的試驗:
將回調值設置為一個在 function 外面的 object:
let deps = {grewer: 1}
在點擊按鈕時:
deps.grewer = deps.grewer + 1;
console.log(deps)
可以發現:
deps.grewer 的值在變化,但是 effect 卻沒有觸發
而這樣設置值時:
deps = {grewer: deps.grewer + 1};
每次都會觸發 effect 函數
再次試驗:
deps = Object.assign({}, deps)
同樣地 每次都會觸發 effect 函數
得出結論:
- 當依賴值為 object 時,他的值引用發生變化就會觸發 effect 的更新
- 但是如果只是對象里某個值變化而引用不變化,effect 依舊不會觸發
關於 function 的試驗結論:
-
如果初始值為 function, 而將其改為數字等,會觸發 effect
-
function 也是一個對象,當我們添加一個值在上面時,他的 effect 也不會觸發
-
引用為一個新函數時,他每次都會觸發;
試驗完畢,相信大家對於 effect 也有了許多的了解
后續還會講述其他 hooks api 與 redux 的全面轉換, eslint 的新配置等