鐵人賽
React
javascript
nodejs
鐵人賽第19天,我們來好好了解一下useEffect
,同時,我們也會學習React的生命週期
!
React
定義了component
的生命週期,提供開發者能夠精準的設置相對應的動作。Render
做一個時間軸的分隔線,後面的代表component
已繪製於畫面中,其中:
- ComponentDidMount: 元件已經完成繪製
- *ComponentDidUpdate: state已經更新完成
- ComponrntWillUnMount: 元件即將移除畫面
EffectApp.js
,同時將index.js
引入使用。EffectApp
組件組成有:
- 一個
div
顯示title- 一個
button
,有toggle
的功能,實現state
的切換,決定title
是否顯示
//EffectApp.js
import React, { useState, useEffect } from "react"; //<-- import引入 useEffect
export default function EffectApp() {
const [state, setState] = useState(true);
// 建立一個useEffect
useEffect(() => {
console.log("ComponentDidMount...");
});
let handleClick = (setState) => {
return (e) => {
setState(!state);
};
};
return (
<>
<button onClick={handleClick(setState)}>{state?"delete":"show"}</button>
<div>{state&& "Learn useEffect"}</div>
</>
);
}
ComponentDidMount...
已經顯示於console window
中,代表所有的component
已經顯示於畫面之上囉!//EffectApp.js
import React, { useState, useEffect } from "react";
export default function EffectApp() {
const [state, setState] = useState(true);
useEffect(() => {
console.log("ComponentDidMount...");
return () => console.log("ComponentDidUpdate!!!"); //<-- 在這裡回傳一個func,當狀態改變時,React會自動呼叫這個函式執行
});
let handleClick = (setState) => {
return (e) => {
setState(!state);
};
};
return (
<>
<button onClick={handleClick(setState)}>{state?"delete":"show"}</button>
<div>{state&& "Learn useEffect"}</div>
</>
);
}
console window
會依序印出
- 狀態改變 => 呼叫回傳的func
return () => console.log("ComponentDidUpdate!!!");
- 元件消失或出現 => 呼叫
console.log("ComponentDidMount...");
Array
,提供給React
決定要呼叫的//EffectApp.js
import React, { useState, useEffect } from "react";
export default function EffectApp() {
const [state1, setState1] = useState(true);
const [state2, setState2] = useState(true);
// for state1
useEffect(() => {
console.log("*** area1 ***");
console.log("[state1]: ComponentDidMount...");
return () => console.log("[state1]: ComponentDidUpdate!!!");
}, [state1]);
// for state2
useEffect(() => {
console.log("=== area2 ===");
console.log("[state2]: ComponentDidMount...");
return () => console.log("[state2]: ComponentDidUpdate!!!");
},[state2]);
let handleClick = (setState, aState) => {
return (e) => {
setState(!aState);
};
};
return (
<>
<button onClick={handleClick(setState1, state1)}>{state1?"delete1":"show1"}</button>
<div>{state1&& "area1"}</div>
<br/>
<button onClick={handleClick(setState2, state2)}>{state1?"delete2":"show2"}</button>
<div>{state2&& "area2"}</div>
</>
);
}
ComponentDidMount
都有被呼叫,符合期待ComponentDidUpdate
先被觸發,因為state1
確實被更新了!area1
的title
消失,因此呼叫ComponentDidMount
,符合預期!area1
的按鈕一樣,也符合我們對state2
的預期useEffect
的第二個變數,給予空的Array
,來看看會有什麼有趣的事//EffectApp.js
...
// for state2
useEffect(() => {
console.log("=== area2 ===");
console.log("[state2]: ComponentDidMount...");
return () => console.log("[state2]: ComponentDidUpdate!!!");
},[]); //<-- 給空的陣列,看看會有什麼有趣的事
...
area2
的ComponentDidMount
在畫面一開始顯示時有被呼叫,之後,不管我怎麼按area2
的按鈕,他都不會有任何反應,React
會依據第二個參數的Array內容
,來決定是否觸發ComponentDidMount
及ComponentDidUpdate
useEffect
第二個參數給予空的陣列,僅會執行一次!React Hook
中,ComponentWillUnMount
及ComponentDidUpdate
都會跟著呼叫你回傳的函示。useEffect(()=>{
// component did Mount
return ()=>{
// component did update
// componrnt will unMount
}
}, [
// 空陣列代表僅執行一次,
// 放入state或component,代表只要他們有變動,就會觸發呼叫useEffect
//])
useEffect
及React lifecycle
之間的關係,useEffect
有很多進階的應用,我們會在未來好好的跟各位詳談,請期待!