Správa zdrojů v Reactu pomocí hooku use: Optimalizace životních cyklů zdrojů pro maximální výkon | MLOG | MLOG

Vysvětlení:

Příklad 2: Správa WebSocket připojení

Tento příklad ukazuje, jak spravovat WebSocket připojení pomocí hooku „use“ a vlastního obalovače zdroje.

            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;

Vysvětlení:

Příklad 3: Správa souborových popisovačů (File Handles)

Tento příklad ilustruje správu zdrojů pomocí hooku „use“ s použitím souborových popisovačů z NodeJS (Tento příklad bude fungovat pouze v prostředí NodeJS a je určen k demonstraci konceptů životního cyklu zdrojů).

            // 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;

Vysvětlení:

Pokročilé techniky: Error Boundaries, sdružování zdrojů (Resource Pooling) a Server Components

Kromě základních příkladů lze hook „use“ kombinovat s dalšími funkcemi Reactu k implementaci sofistikovanějších strategií správy zdrojů.

Error Boundaries: Elegantní zpracování chyb

Error boundaries jsou React komponenty, které zachytávají JavaScriptové chyby kdekoli ve svém stromu podřízených komponent, tyto chyby logují a zobrazují záložní UI místo toho, aby se zhroutil celý strom komponent. Při použití hooku „use“ je klíčové obalit vaše komponenty error boundaries, abyste zvládli potenciální chyby během načítání dat nebo inicializace zdrojů.

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

Sdružování zdrojů (Resource Pooling): Optimalizace znovupoužití zdrojů

V některých scénářích může být časté vytváření a ničení zdrojů nákladné. Sdružování zdrojů (resource pooling) zahrnuje udržování fondu znovupoužitelných zdrojů, aby se minimalizovaly náklady na jejich vytváření a ničení. Ačkoli hook „use“ sám o sobě neimplementuje sdružování zdrojů, lze ho použít ve spojení se samostatnou implementací fondu zdrojů.

Zvažte fond databázových připojení. Místo vytváření nového připojení pro každý požadavek můžete udržovat fond předem navázaných připojení a znovu je používat. Hook „use“ lze použít ke správě získávání a uvolňování připojení z fondu.

(Konceptuální příklad - implementace se liší v závislosti na konkrétním zdroji a knihovně pro sdružování):

            // 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 (RSCs): Přirozené prostředí pro hook „use“

Hook „use“ byl původně navržen pro React Server Components. RSC se vykonávají na serveru, což vám umožňuje načítat data a provádět další operace na straně serveru, aniž byste posílali kód klientovi. To výrazně zlepšuje výkon a zmenšuje velikost JavaScriptových balíčků na straně klienta.

V RSC lze hook „use“ použít k přímému načítání dat z databází nebo API bez nutnosti klientských knihoven pro načítání dat. Data se načtou na serveru a výsledné HTML je odesláno klientovi, kde je hydratováno Reactem.

Při použití hooku „use“ v RSC je důležité si uvědomit omezení RSC, jako je absence stavu na straně klienta a obsluhy událostí. RSC však lze kombinovat s komponentami na straně klienta a vytvářet tak výkonné a efektivní aplikace.

Doporučené postupy pro efektivní správu zdrojů s „use“

Chcete-li maximalizovat přínosy hooku „use“ pro správu zdrojů, dodržujte tyto osvědčené postupy:

Běžné nástrahy a jak se jim vyhnout

Ačkoli hook „use“ nabízí řadu výhod, je důležité si být vědom potenciálních nástrah a vědět, jak se jim vyhnout.

Závěr: Přijetí hooku „use“ pro optimalizované React aplikace

React hook „use“ představuje významný pokrok ve správě zdrojů v rámci React aplikací. Zjednodušením zpracování asynchronních dat, automatizací úklidu zdrojů a bezproblémovou integrací se Suspense dává vývojářům možnost vytvářet výkonnější, udržovatelnější a uživatelsky přívětivější aplikace.

Pochopením základních konceptů, prozkoumáním praktických příkladů a dodržováním osvědčených postupů můžete efektivně využít hook „use“ k optimalizaci životních cyklů zdrojů a odemknout plný potenciál vašich React aplikací. Jak se React neustále vyvíjí, hook „use“ bude nepochybně hrát stále důležitější roli při formování budoucnosti správy zdrojů v ekosystému Reactu.