React use Hook Erőforrás-kezelés: Az Erőforrás Életciklusok Optimalizálása a Csúcsteljesítményért | MLOG | MLOG

Magyarázat:

2. példa: WebSocket kapcsolatok kezelése

Ez a példa bemutatja, hogyan lehet egy WebSocket kapcsolatot kezelni a "use" Hook és egy egyedi erőforrás-csomagoló segítségével.

            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;

Magyarázat:

3. példa: Fájlkezelők (File Handles) menedzselése

Ez a példa az erőforrás-kezelést a "use" Hookkal NodeJS fájlkezelők segítségével szemlélteti (Ez csak NodeJS környezetben fog működni, és célja az erőforrás-életciklus koncepcióinak bemutatása).

            // This example is designed for a NodeJS environment

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;

Magyarázat:

Haladó technikák: Error Boundary-k, Erőforrás-készletezés és Server Components

Az alapvető példákon túl a "use" Hook kombinálható más React funkciókkal is, hogy kifinomultabb erőforrás-kezelési stratégiákat valósítsunk meg.

Error Boundary-k: A hibák elegáns kezelése

Az Error Boundary-k olyan React komponensek, amelyek elkapják a JavaScript hibákat a gyermekkomponens-fájuk bármely pontján, naplózzák ezeket a hibákat, és egy tartalék (fallback) felhasználói felületet jelenítenek meg ahelyett, hogy az egész komponensfa összeomlana. A "use" Hook használatakor kulcsfontosságú, hogy a komponenseinket Error Boundary-kkal vegyük körül az adatlekérés vagy erőforrás-inicializálás során fellépő esetleges hibák kezelésére.

            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...
}> ); }

Erőforrás-készletezés (Resource Pooling): Az erőforrás-újrahasznosítás optimalizálása

Bizonyos esetekben az erőforrások gyakori létrehozása és megsemmisítése költséges lehet. Az erőforrás-készletezés (resource pooling) egy újrahasznosítható erőforrásokból álló készlet fenntartását jelenti, hogy minimalizáljuk az erőforrás-létrehozás és -megsemmisítés overheadjét. Bár a "use" hook önmagában nem valósít meg erőforrás-készletezést, használható egy külön erőforrás-készlet implementációval együtt.

Vegyünk egy adatbázis-kapcsolatkészletet (connection pool). Ahelyett, hogy minden kéréshez új kapcsolatot hoznánk létre, fenntarthatunk egy készletet előre létrehozott kapcsolatokból és újra felhasználhatjuk őket. A "use" Hook használható a kapcsolatok készletből való megszerzésének és visszaadásának kezelésére.

(Koncepcionális példa - a megvalósítás az adott erőforrástól és a készletező könyvtártól függően változik):

            // Conceptual Example (not a complete, runnable implementation)

import React, { use } from 'react';
// Assume a database connection pool library exists
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 (RSC): A "use" Hook természetes otthona

A "use" Hookot eredetileg a React Server Components komponensekhez tervezték. Az RSC-k a szerveren futnak, lehetővé téve az adatlekérést és más szerveroldali műveletek elvégzését anélkül, hogy kódot küldenénk a kliensnek. Ez jelentősen javítja a teljesítményt és csökkenti a kliensoldali JavaScript csomagméreteket.

Az RSC-kben a "use" Hook közvetlenül használható adatok lekérésére adatbázisokból vagy API-kból, kliensoldali adatlekérő könyvtárak nélkül. Az adatok a szerveren kerülnek lekérésre, és az eredményül kapott HTML-t küldik el a kliensnek, ahol azt a React hidratálja.

A "use" Hook RSC-kben való használatakor fontos tisztában lenni az RSC-k korlátaival, például a kliensoldali állapot (state) és eseménykezelők hiányával. Azonban az RSC-k kombinálhatók kliensoldali komponensekkel, hogy erőteljes és hatékony alkalmazásokat hozzunk létre.

Bevált gyakorlatok a hatékony erőforrás-kezeléshez a "use" Hookkal

A "use" Hook erőforrás-kezelési előnyeinek maximalizálása érdekében kövesse az alábbi bevált gyakorlatokat:

Gyakori buktatók és elkerülésük

Bár a "use" Hook számos előnnyel jár, fontos tisztában lenni a lehetséges buktatókkal és azok elkerülésének módjaival.

Összegzés: A "use" Hook alkalmazása az optimalizált React alkalmazásokért

A React "use" Hook jelentős előrelépést jelent az erőforrás-kezelés terén a React alkalmazásokban. Az aszinkron adatkezelés egyszerűsítésével, az erőforrás-tisztítás automatizálásával és a Suspense-szel való zökkenőmentes integrációval lehetővé teszi a fejlesztők számára, hogy teljesítményesebb, karbantarthatóbb és felhasználóbarátabb alkalmazásokat építsenek.

Az alapkoncepciók megértésével, a gyakorlati példák feltárásával és a bevált gyakorlatok követésével hatékonyan kihasználhatja a "use" Hookot az erőforrás-életciklusok optimalizálására és a React alkalmazásai teljes potenciáljának kiaknázására. Ahogy a React tovább fejlődik, a "use" Hook kétségtelenül egyre fontosabb szerepet fog játszani az erőforrás-kezelés jövőjének alakításában a React ökoszisztémában.