Manajemen Sumber Daya Hook 'use' React: Mengoptimalkan Siklus Hidup Sumber Daya untuk Performa Puncak | MLOG | MLOG

Penjelasan:

Contoh 2: Mengelola Koneksi WebSocket

Contoh ini menunjukkan cara mengelola koneksi WebSocket menggunakan Hook "use" dan pembungkus sumber daya kustom.

            import React, { useState, useEffect, use } from 'react';

const createWebSocketResource = (url) => {
  let socket;
  let status = 'pending';
  let messageQueue = [];
  let listeners = [];

  const connect = () => {
    return new Promise((resolve, reject) => {
      socket = new WebSocket(url);

      socket.onopen = () => {
        status = 'connected';
        resolve();
        // Send queued messages
        messageQueue.forEach(msg => socket.send(msg));
        messageQueue = [];
      };

      socket.onerror = (error) => {
        status = 'error';
        reject(error);
      };

      socket.onmessage = (event) => {
        listeners.forEach(listener => listener(event.data));
      };

      socket.onclose = () => {
        status = 'closed';
        listeners = []; // Clear listeners to avoid memory leaks
      };
    });
  };

  const promise = connect();

  return {
    read() {
      use(promise);
    },
    send(message) {
      if (status === 'connected') {
        socket.send(message);
      } else {
        messageQueue.push(message);
      }
    },
    subscribe(listener) {
      listeners.push(listener);
      return () => {
        listeners = listeners.filter(l => l !== listener);
      };
    },
    close() {
        if (socket && socket.readyState !== WebSocket.CLOSED) {
            socket.close();
        }
    }
  };
};

function WebSocketComponent({ url }) {
  const socketResource = createWebSocketResource(url);
  // Suspend until connected
  socketResource.read();
  const [message, setMessage] = useState('');
  const [receivedMessages, setReceivedMessages] = useState([]);

  useEffect(() => {
    const unsubscribe = socketResource.subscribe(data => {
      setReceivedMessages(prevMessages => [...prevMessages, data]);
    });
    return () => {
        unsubscribe();
        socketResource.close();
    };
  }, [socketResource]);

  const sendMessage = () => {
    socketResource.send(message);
    setMessage('');
  };

  return (
    
setMessage(e.target.value)} />
Received Messages:
    {receivedMessages.map((msg, index) => (
  • {msg}
  • ))}
); } function App() { return ( Connecting to WebSocket...
}> ); } export default App;

Penjelasan:

Contoh 3: Mengelola Penangan Berkas (File Handles)

Contoh ini mengilustrasikan manajemen sumber daya dengan Hook "use" menggunakan penangan berkas NodeJS (Ini hanya akan berfungsi di lingkungan NodeJS dan dimaksudkan untuk menampilkan konsep siklus hidup sumber daya).

            // Contoh ini dirancang untuk lingkungan NodeJS

const fs = require('node:fs/promises');
import React, { use } from 'react';

const createFileHandleResource = async (filePath) => {
  let fileHandle;

  const openFile = async () => {
    fileHandle = await fs.open(filePath, 'r');
    return fileHandle;
  };

  const promise = openFile();

  return {
    read() {
      return use(promise);
    },
    async close() {
      if (fileHandle) {
        await fileHandle.close();
        fileHandle = null;
      }
    },
    async readContents() {
      const handle = use(promise);
      const buffer = await handle.readFile();
      return buffer.toString();
    }
  };
};


function FileViewer({ filePath }) {
  const fileHandleResource = createFileHandleResource(filePath);
  const contents = fileHandleResource.readContents();

  React.useEffect(() => {
    return () => {
      // Cleanup when the component unmounts
      fileHandleResource.close();
    };
  }, [fileHandleResource]);

  return (
    

File Contents:

{contents}
); } // Example Usage async function App() { const filePath = 'example.txt'; await fs.writeFile(filePath, 'Hello, world!\nThis is a test file.'); return (
); } export default App;

Penjelasan:

Teknik Lanjutan: Error Boundaries, Resource Pooling, dan Server Components

Selain contoh dasar, Hook "use" dapat dikombinasikan dengan fitur React lainnya untuk mengimplementasikan strategi manajemen sumber daya yang lebih canggih.

Error Boundaries: Menangani Kesalahan dengan Anggun

Error boundaries adalah komponen React yang menangkap kesalahan JavaScript di mana saja dalam pohon komponen turunannya, mencatat kesalahan tersebut, dan menampilkan UI fallback alih-alih merusak seluruh pohon komponen. Saat menggunakan Hook "use", sangat penting untuk membungkus komponen Anda dengan error boundaries untuk menangani potensi kesalahan selama pengambilan data atau inisialisasi sumber daya.

            import React, { Component } from 'react';

class ErrorBoundary extends Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    // Update state so the next render will show the fallback UI.
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    // You can also log the error to an error reporting service
    console.error(error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      // You can render any custom fallback UI
      return 

Something went wrong.

; } return this.props.children; } } function App() { return ( Loading...
}> ); }

Resource Pooling: Mengoptimalkan Penggunaan Kembali Sumber Daya

Dalam beberapa skenario, membuat dan menghancurkan sumber daya secara sering bisa jadi mahal. Resource pooling melibatkan pemeliharaan kumpulan sumber daya yang dapat digunakan kembali untuk meminimalkan overhead pembuatan dan penghancuran sumber daya. Meskipun hook "use" tidak secara inheren mengimplementasikan resource pooling, ia dapat digunakan bersama dengan implementasi resource pool terpisah.

Pertimbangkan sebuah pool koneksi database. Alih-alih membuat koneksi baru untuk setiap permintaan, Anda dapat memelihara kumpulan koneksi yang sudah ada dan menggunakannya kembali. Hook "use" dapat digunakan untuk mengelola perolehan dan pelepasan koneksi dari pool tersebut.

(Contoh Konseptual - Implementasi bervariasi tergantung pada sumber daya spesifik dan pustaka pooling):

            // Contoh Konseptual (bukan implementasi lengkap yang dapat dijalankan)

import React, { use } from 'react';
// Asumsikan pustaka pool koneksi database ada
import { getConnectionFromPool, releaseConnectionToPool } from './dbPool';

const createDbConnectionResource = () => {
  let connection;

  const acquireConnection = async () => {
    connection = await getConnectionFromPool();
    return connection;
  };

  const promise = acquireConnection();

  return {
    read() {
      return use(promise);
    },
    release() {
      if (connection) {
        releaseConnectionToPool(connection);
        connection = null;
      }
    },
    query(sql) {
      const conn = use(promise);
      return conn.query(sql);
    }
  };
};

function MyDataComponent() {
  const dbResource = createDbConnectionResource();

  React.useEffect(() => {
    return () => {
      dbResource.release();
    };
  }, [dbResource]);

  const data = dbResource.query('SELECT * FROM my_table');
  return 
{data}
; }

React Server Components (RSCs): Rumah Alami dari Hook "use"

Hook "use" pada awalnya dirancang untuk React Server Components. RSCs dieksekusi di server, memungkinkan Anda untuk mengambil data dan melakukan operasi sisi server lainnya tanpa mengirim kode ke klien. Ini secara signifikan meningkatkan performa dan mengurangi ukuran bundel JavaScript sisi klien.

Di RSCs, Hook "use" dapat digunakan untuk langsung mengambil data dari database atau API tanpa memerlukan pustaka pengambilan data sisi klien. Data diambil di server, dan HTML yang dihasilkan dikirim ke klien, di mana ia dihidrasi oleh React.

Saat menggunakan Hook "use" di RSCs, penting untuk menyadari batasan RSCs, seperti tidak adanya state sisi klien dan event handlers. Namun, RSCs dapat dikombinasikan dengan komponen sisi klien untuk menciptakan aplikasi yang kuat dan efisien.

Praktik Terbaik untuk Manajemen Sumber Daya yang Efektif dengan "use"

Untuk memaksimalkan manfaat dari Hook "use" untuk manajemen sumber daya, ikuti praktik terbaik ini:

Kesalahan Umum dan Cara Menghindarinya

Meskipun Hook "use" menawarkan banyak manfaat, penting untuk menyadari potensi kesalahan dan cara menghindarinya.

Kesimpulan: Merangkul Hook "use" untuk Aplikasi React yang Dioptimalkan

Hook "use" React merepresentasikan kemajuan signifikan dalam manajemen sumber daya dalam aplikasi React. Dengan menyederhanakan penanganan data asinkron, mengotomatiskan pembersihan sumber daya, dan berintegrasi secara mulus dengan Suspense, ini memberdayakan pengembang untuk membangun aplikasi yang lebih berperforma, dapat dipelihara, dan ramah pengguna.

Dengan memahami konsep inti, menjelajahi contoh praktis, dan mengikuti praktik terbaik, Anda dapat secara efektif memanfaatkan Hook "use" untuk mengoptimalkan siklus hidup sumber daya dan membuka potensi penuh aplikasi React Anda. Seiring React terus berkembang, Hook "use" tidak diragukan lagi akan memainkan peran yang semakin penting dalam membentuk masa depan manajemen sumber daya di ekosistem React.