1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>ReactJS</title> </head> <body> <div id="app"></div> <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script> <script type="text/babel"> const { useState, useEffect, useRef } = React function App(props) { const [count, setCount] = useState(0) const [number, setNumber] = useState(0) useEffect(() => { console.log("Dependencies = [count] =>= Chạy khi 'count' thay đổi") setNumber(number + 1) return ()=> { console.log("Cleanup [count] ==> Cleanup trước khi chạy code trong useEffect [count] --") } }, [count]) console.log("1. Luôn luôn chạy, và code bên ngoài luôn chạy trước code trong useEffect") useEffect(() => { console.log("Dependencies = [] ==> Chạy duy nhất 1 lần khi khởi tại") return ()=> { console.log("Cleanup []") } }, []) useEffect(() => { console.log("Dependencies = undefined ==> Luôn luôn chạy") return ()=> { console.log("Cleanup undefined") } }) // 2. Chạy render return ( <div> <p>Count: {count}</p> <button onClick={() => { setCount(count + 1) }}> Increase </button> <p>Number: {count}</p> <button onClick={() => { setNumber(number + 1) }}> Increase </button> </div> ) } ReactDOM.render(<App />, document.getElementById('app')) </script> </body> </html> |
1. Side effects có 2 loại
1.1. Effects không cần clean up
-- Gọi API lấy dữ liệu
-- Tương tác với DOM
1.2. Effects cần clean up
-- Subscriptions
-- setTimeout, setInterval
2. Cấu trúc useEffect
1 2 3 4 5 6 7 8 9 10 11 12 13 |
const useEffect = React.useEffect function App(props) { useEffect(() => { //code 'side effect' return () => { //code 'cleanup' } }, //vị trí 'dependencies' [] ) return <div>rendering</div> } |
1. Mouting: Code chạy lần đầu
-- Run rendering
-- Run code khu vực 'side effect'
2. Khi Updating
-- Run rendering
-- Run code khu vực 'cleanup' nếu 'dependencies' thay đổi
-- Run code khu vực 'side effect' nếu 'dependencies' thay đổi
3. Khi Unmounting
-- Run code khu vực 'cleanup'
3. Sự khác nhau giữa các cách viết dependencies
-- 1. Không khai báo 'dependencies'
1 2 3 4 5 6 7 |
useEffect(() => { // code 'side effect' ---> luôn chạy sau mỗi lần render return () => { // code 'cleanup' } }) return <div>rendering</div> |
-- 2. Nếu là 1 mảng rỗng: []
1 2 3 4 5 6 7 |
useEffect(() => { // code 'side effect' ---> chạy đúng 1 lần duy nhất sau lần render đầu tiên (tương tự ComponentDidmount) return () => { // code 'cleanup' --> chạy đúng 1 lần khi unmount (tương tự ComponentWilUnmout) } },[]) return <div>rendering</div> |
-- 3. Nếu là 1 mảng có dữ liệu: [custom]
1 2 3 4 5 6 7 8 9 10 |
useEffect(() => { // code 'side effect' // chạy lần khi render lần đầu tiên // các lần render tiếp theo phụ thuộc vào 'dependencies' có thay đổi hay không return () => { // code 'cleanup' // nếu 'dependencies' thay đổi --> chạy 'cleanup' --> sau đó chạy 'side effect' } },[custom]) return <div>rendering</div> |