This page looks best with JavaScript enabled

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

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

Nội dung ở phần này mình muốn đưa cho các bạn sẽ có 3 phần chính:

  • Cách listen DOMEvent trong React component
  • Vấn để xảy ra khi chúng ta listen DOM Event là gì?
  • Cách khắc phục vấn đề nàymột

Trong phần này, chúng ta phải nắm vững kiến thức Javascript cơ bản đó là listen DOM Event bạn có thể tham khảo tài liệu tại đây Listen DOM Event

Mình sẽ xác định rõ ngay từ đầu là khi thực hiện một logic mới, chúng ta sẽ viết ra 1 useEffect mới

Bây giờ chúng ta sẽ làm 1 ví dụ, đó là khi chúng ta cuộn chuột xuống 1 khoảng lớn hơn hoặc = 200 px thì sẽ hiện 1 nút Go to top
để hiện lên trang đầu, như trong blog này của mình cũng có tính năng này.

Ở trường hợp này chúng ta sẽ đi listenDOM 1 lần, khi đó chúng ta sẽ truyền dependencies vào là []

1
2
3
4
5
6
useEffect(() => {
        const handleScroll = () =>{
            console.log(window.scrollY)
        }
        window.addEventListener('scroll', handleScroll)
    }, [])

ở đây chúng ta sẽ code Javascript thuần, để có thể ẩn hiện được button go to top, chúng ta cần phải re render lại giao diện, với ReactJs chúng ta sẽ dùng hoook
useState mà chúng ta đã tìm hiểu ở các phần trước.

 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
function Content() {
    const [title, setTitle] = useState('')
    const [posts, setPosts] = useState([])
    const [types, setTypes] = useState(['posts'])
    const [showGoToTop, setShowGoToTop] = useState(false)
    useEffect(
        () =>{
            console.log('title changed')
            document.title = title;
            fetch(`https://jsonplaceholder.typicode.com/${types}`)
            .then(res => res.json())
            .then(posts =>{
                setPosts(posts)
            })
        },[types]
    )
    useEffect(() => {
        const handleScroll = () =>{
            if(window.scrollY >= 200){
                setShowGoToTop(true)
            }else{
                setShowGoToTop(false)
            }
        }
        window.addEventListener('scroll', handleScroll)
    }, [])

Sau đó mình sẽ viết 1 đoạn code để ẩn hiện button go to top theo state bên trên

1
2
3
4
5
6
7
8
9
 {showGoToTop && (
                <button style={{
                    position: 'fixed',
                    right: 20,
                    bottom: 20
                }}>
                    Go to top
                </button>
            )}

Và kết quả sẽ như sau:

Tuy nhiên nếu các bạn để ý thì chúng ta sẽ thấy rằng, nếu chúng ta tiếp tục kéo chuột xuống thì useEffect sẽ liên tục được gọi
dẫn tới việc liên tục re render lại giao diện? Câu trả lời là không, ReactJS đã giúp chúng ta ngăn chặn việc đó. Có nghĩ là mặc dù hàm trong useEffect được gọi lại liên tục nhưng
component sẽ không bị re render lại.

Đến với 1 vấn đề tiếp theo, bây giờ chúng ta thử unmount component rồi mount lại, xong đó kéo chuột xuống, sẽ có 1 thông báo mà ReactJS báo cho chúng ta như sau:

Đó là bởi vì khi component của chúng ta unmount thì Event Listen chúng ta thêm vào chưa được xóa đi, dẫn tới việc khi chúng ta mount lại component thì 1 event
listen nữa lại được thêm vào, điều này dẫn đến lãng phí tài nguyên, dò rỉ bộ nhớ. Vậy giải pháp ở đây là gì? Đó chính là Cleanup Function và trong callback
của useEffect các bạn có thể return ra 1 hàm

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
useEffect(() => {
        const handleScroll = () =>{
            if(window.scrollY >= 200){
                setShowGoToTop(true)
            }else{
                setShowGoToTop(false)
            }
        }
        window.addEventListener('scroll', handleScroll)
        // cleanup function
        return () => window.removeEventListener('scroll', handleScroll)
    }, [])

Hy vọng sau phần này bạn sẽ nắm rõ cách xử lý DOM event trong Reactjs 😄. Bye bye

Chia sẻ
Support the author with

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