Q1. Life cycle của useEffect trong React Native?

Trong React Native, useEffect là một hook dùng để xử lý các side effect trong các functional component. Hiểu rõ life cycle của useEffect sẽ giúp bạn biết khi nào và tại sao nó được gọi.

Dưới đây là giải thích chi tiết về life cycle của useEffect:

Mounting (gắn kết)

Mounting là giai đoạn khi component được gắn vào cây DOM

Có 3 trường hợp có thể xảy ra trong giai đoạn này đối với useEffect:

  • Khi useEffect không có dependency array ('[]'):

      useEffect(() => {
        // Code này chạy mỗi khi component được render.
      });
    

    useEffect này sẽ chạy sau mỗi lần render, tức là mỗi khi component hoặc các state bên trong nó thay đổi.

  • Khi useEffect có dependency array rỗng ('[]'):

      useEffect(() => {
        // Code này chỉ chạy một lần khi component được mount.
      }, []);
    

    useEffect này sẽ chỉ chạy một lần duy nhất khi component được mounting và không chạy lại khi component re-render.

  • Khi useEffect có dependency array với các dependencies cụ thể ('[dep1, dep2]'):

      useEffect(() => {
        // Code này chạy mỗi khi giá trị của dep1 hoặc dep2 thay đổi.
      }, [dep1, dep2]);
    

    useEffect này sẽ chỉ chạy khi một trong các dependencies trong array thay đổi.

Updating (cập nhật)

Updating là giai đoạn khi component được cập nhật (tức là khi các props hoặc state thay đổi)

  • Khi useEffect không có dependency array ([]):

      useEffect(() => {
        // Code này chạy mỗi khi component được cập nhật hoặc re-render.
      });
    
  • Khi useEffect có dependency array rỗng ([]):

      useEffect(() => {
        // Code này không chạy lại khi component cập nhật.
      }, []);
    
  • Khi useEffect có dependency array với các dependencies cụ thể ([dep1, dep2]):

      useEffect(() => {
        // Code này chỉ chạy khi giá trị của dep1 hoặc dep2 thay đổi.
      }, [dep1, dep2]);
    

Unmounting (gỡ bỏ)

Unmounting là giai đoạn khi component bị gỡ bỏ khỏi cây DOM

  • Cleanup function

      useEffect(() => {
        // Code để thiết lập hiệu ứng.
        return () => {
          // Code này chạy khi component bị gỡ bỏ khỏi cây DOM.
          // Dùng để dọn dẹp các hiệu ứng, hủy bỏ subscriptions, hoặc giải phóng tài nguyên.
        };
      }, []);
    

    Cleanup function trong useEffect được gọi trong hai tình huống chính:

    1. Trước khi component bị gỡ bỏ khỏi cây DOM (unmount), cleanup function sẽ được gọi một lần để dọn dẹp side effects

    2. Trước khi chạy lại useEffect do dependencies thay đổi, điều này giúp đảm bảo rằng mọi side effect từ lần chạy trước đều được dọn dẹp trước khi thiết lập một side effect mới

Ví dụ minh hoạ:

import React, { useState, useEffect } from 'react';
import { View, Text } from 'react-native';

const MyComponent = () => {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log('Effect is running');

    return () => {
      console.log('Cleanup function is running');
    };
  }, [count]);

  return (
    <View>
      <Text onPress={() => setCount(count + 1)}>Click me</Text>
      <Text>Count: {count}</Text>
    </View>
  );
};

export default MyComponent;

Trong ví dụ trên:

  • useEffect sẽ chạy mỗi khi count thay đổi

  • Cleanup function sẽ chạy trước khi useEffect thiết lập lại side effect với giá trị mới của count

Flow hoạt động trong đoạn code trên:

  • Giai đoạn 1: Component mounting:

    • useEffect chạy lần đầu tiên

    • Effect is running được in ra console

  • Giai đoạn 2: Component updating:

    • Cleanup function từ lần chạy trước được gọi

    • Cleanup function is running được in ra console

    • useEffect chạy lại với giá trị mới của count

    • Effect is running được in ra console

  • Giai đoạn 3: Component unmounting

    • Cleanup function được gọi lần cuối

    • Cleanup function is running được in ra console