React 基礎:useEffect 與 Hooks


初探 useEffect

render 完以後,瀏覽器 paint 之後你想要做什麼?

  • 每一次 render 之後,都去執行 useEffect 內的 function
useEffect(() => {
    console.log("alert render")
})
  • 在某些 state 改變的時候,去執行 useEffect 內的 function
    在 function 裡面加入第二個參數之後,當 todos 改變的時候,才去執行這個 useEffect
function writeTodoToLocalStorage(todos) {
    window.localStorage.setItem("todos", JSON.stringify(todos));
}

useEffect(() => {
    writeTodoToLocalStorage(todos)
}, [todos]);
// 加入第二個參數之後,當 todos 改變的時候,才去執行這個 useEffect
  • 第二個參數,當裡面是空的時候(表示不會變),表示只有在第一次 render 完之後,才會執行這個 useEffect,第二次、第三次都不會
    (注意:若是有初始值,在瀏覽器畫完畫面之後,才會去執行 useEffect,這樣會造成畫面會「閃一下」)
function writeTodoToLocalStorage(todos) {
    window.localStorage.setItem("todos", JSON.stringify(todos));
}

useEffect(() => {
    const todoData = window.localStorage.getItem('todos') || ""
    if (todoDate) {
        setTodos(JSON.parse(todoData));
    }
}, []);

什麼是 useLayoutEffect

render 完之後,瀏覽器 paint 「之前」你想做什麼?

  • 改善畫面會「閃一下」的狀況
useLayoutEffect(() => {
    const todoData = window.localStorage.getItem('todos') || ""
    if (todoDate) {
        setTodos(JSON.parse(todoData));
    }
}, []);
  • React Hook Flow Diagram

圖片來源

  • Run lazy initializers
    在 useState 後面放 function(即是 lazy initializers)
    function return 的東西會變成我們的初始值
const [todos, setTodos] = useState(() => {
    console.log("init");
    let todoData = window.localStorage.getItem("todos") || "";
    if (todoData) {
        todoData = JSON.parse(todoData);
        id.current = todoData[0].id + 1;
    } else {
        todoData = []
    }
})

再進一步了解 useEffect

  • Cleanup LayoutEffect
    在 useEffect 被清掉之前,想要做什麼事情?
useEffect(() => {
    const todoData = window.localStorage.getItem('todos')

    // clean up function
    return () => {
    }
}, [todos]);
第一次 render
第一次的 App()
todos: [{"id":1, "content":"123"}]

useEffect(() => {
    const todoData = window.localStorage.getItem('todos')


    return () => {
        // clean up function
    }
}, [todos]);

---

第二次 render,App()
todos: todos [{"id":1, "content":"123", "isDone":true}]
清掉 effect,再執行一次 useEffect
  • Unmount
    在 component 消失前,要做什麼事。
useEffect(() => {
    return () => {
        consoloe.log('unmount')
    }    
}, []);

寫一個自己的 hook!

抽出邏輯來共用,UI隨不同畫面而變化。
@ useInput.js

import { useState } from 'react';

export default function useInput() {
    const [value, setValue] = useSate("");
    const handleChange = e => {
        setValue(e.targetValue)
    }

    return {
        value,
        setValue,
        handleChange,
    };
}

@ App.js

import unsInput from './useInput'

const { value, setValue, handleChange } = useInput()
const { todos, setTodos } = useTodos()

function App() {
    return (
        <input 
            type="text"
            placeholder="todo"
            value={value}
            onChange={handleChange}  
        />
    )
}







你可能感興趣的文章

[Day03] Lazy Evaluation

[Day03] Lazy Evaluation

讀書筆記-JavaScript技術手冊3: 函式基本語法

讀書筆記-JavaScript技術手冊3: 函式基本語法

MTR04_0902

MTR04_0902






留言討論