This page looks best with JavaScript enabled

Cách sử dụng useEffect trong ReactJS (Phần 1)

 ·  ☕ 4 phút đọc · 👀... views

useEffect là 1 hook cơ bản trong Reactjs, nhưng khi bạn mới học sẽ thấy nó hơi khó một chút😁. Lý do nó khó không phải vì hook
này nó khó mà vì để có thể sử dụng được hook này đòi hỏi bạn phải nắm vững kiến thức Javascript cơ bản và nâng cao. Thế nên
nếu bạn đi vào đây học quá nhanh hoặc quên mất kiến thức nền thì học sẽ bị khó.

Ở đây mình sẽ review cho bạn một số kiến thức mà bạn nên nắm chắc khi học hook này:

  • Events : Bạn nên biết cách làm việc với event trong javascript, bao gồm cả Dom event và custom event do bạn tạo ra, biết cách
  • sử dụng add/remove event listener, hiểu tại sao phải remove event listener
  • Observer parttern : (Subscribe/unsubcribe) Đây là 1 dạng triển khai mở rông của tư tưởng add/remove listener, bản chất cũng là dạng
  • đầu tiên nhưng triển khai ở 1 dạng khác
  • Bạn cần nắm rõ khái niệm hàm đóng Closure trong Javascript.
  • Biết cách làm việc với api dạng timer như setInterval, setTimeout, clearInterval, ClearTimeout.
  • Nắm chắc hook useState.
  • Hiểu rõ khi nào mounted, khi nào unmounted.

Hook này để làm gì và chúng ta dùng nó khi nào?

Chúng ta sẽ dùng useEffect khi các bạn muốn thực hiện các side effect, thuật ngữ này được sử dụng chung trong lĩnh vực phần mềm,
side effect đang nói tới 1 chương trình phần mềm khi có 1 tác động xảy ra dẫn đến dữ liệu bị thay đổi. Mình sẽ đưa
cho bạn một vài ví du quen thuộc để bạn dễ hình dung đó là khi bạn update DOM, call api nhận lại dữ liệu để setState….

Tóm lại useEffect sẽ giúp các bạn update DOM, call API, listen DOM event, remove event listener…

useEffect có 3 tình huống chính khi chúng ta sử dụng:

  • useEffect(callback)
  • useEffect(callback,[])
  • useEffect(callback,[deps])
    Hãy cùng mình đi tìm hiểu từng tình huống và xem cách useEffect hoạt động như thế nào nhé!

1. useEffect(callback)

Với trường họp này, callback sẽ được gọi mỗi khi component được mounted vào trong DOM

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import {useState} from "react";
import { useEffect } from "react";
import Content from "./Content_blog";
function App() {
    const [show,setShow] = useState(false)

    return (
        <div style={{padding: 32}}>
            <button onClick={()=>setShow(!show)}>
                Click
            </button>
            {show && <Content/>}
        </div>
    )
}

export default App;
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import { useEffect } from "react";
import {useState} from "react";

function Content() {
    const [title, setTitle] = useState('')
    useEffect(() => {
        console.log('test12')
      });
    return ( 
        <div>
            <input
            value={title}
            onChange={(e)=> setTitle(e.target.value)} z
            />
        </div>
    )
}
export default Content

ở đây mình có viết 1 useEffect mỗi khi mình click button thì ô input sẽ được hiển thị

Như bạn có thể thấy mỗi khi click button, component sẽ được render lại => dẫn tới việc callback trong trường hợp useEffect
này sẽ được gọi lại, bạn có thể thấy log bên dưới tab console.

Tuy nhiên trường hợp đầu tiên này được sử dụng khá ít trong thực tế và khi sử dụng trường hợp này để call API update lại DOM cũng sẽ xảy ra một điều 😃 cùng mình
xem đó là gì nhé!

Bây giờ mình sẽ call 1 api và update DOM, api mình sẽ lấy ở https://jsonplaceholder.typicode.com.

 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
import { useEffect } from "react";
import {useState} from "react";

function Content() {
    const [title, setTitle] = useState('')
    const [posts, setPosts] = useState([])
    useEffect(
        () =>{
            fetch('https://jsonplaceholder.typicode.com/posts')
            .then(res => res.json())
            .then(posts =>{
                setPosts(posts)
            })
        }
    )
    return ( 
        <div>
            <input
            value={title}
            onChange={(e)=> setTitle(e.target.value)} z
            />
             <ul>
                {posts.map(post =>(
                    <li key={post.id}>{post.title}</li>
                ))}
            </ul>
        </div>
    )
}
export default Content

Có vẻ mọi thứ đã hoạt động rồi nhỉ, tuy nhiên bạn hãy cũng nhìn tab network với mình nhé!

API được gọi liên tục trong 1 vòng lặp vô hạn. Tại sao lại như vậy? Đó chính là khi gọi API xong, chúng ta gọi lại hàm setPost(), dẫn tới việc component
được render lại và rồi theo như lý thuyết của useEffect là callback sẽ được gọi mỗi khi component được mounted vào trong DOM dẫn tới việc xảy ra vòng lặp
vô hạn ở đây. Chính điều này là nguyên nhân mà chúng ta cần sử dụng useEffect với 2 trường hợp còn lại hoặc còn gọi chung là useEffect với dependencies.

Chia sẻ
Support the author with

Hùng Phạm
Viết bởi
Hùng Phạm
Web/Mobile Developer