React의 Web Workers는 React 애플리케이션에서 여러 스레드를 동시에 실행할 수 있게 해주는 기능입니다. 이를 통해 일부 스레드가 백그라운드에서 실행되도록 하여 기본 스레드의 일부로 실행되지 않도록 제외할 수 있습니다.
예를 들어, 현재 실행 중인 메인 스레드의 일반적인 기능을 변경하지 않고 복잡한 계산, API에서 대용량 데이터 가져오기 또는 백그라운드 알림 구현을 수행하려는 애플리케이션이 있다고 가정해 보겠습니다. 이는 모든 프로세스가 React 앱에서 실행되는 동안 사용자 인터페이스가 정지되지 않도록 보장하는 React Web Hooks를 구현함으로써 달성할 수 있습니다.
이 가이드에서는 지수 계산을 수행하기 위해 사용자 정의 React Hooks에서 웹 작업자를 구현하는 샘플 React 프로젝트를 생성합니다.
반응 애플리케이션을 만듭니다.
npx create-vite myproject -- --template react
나는 vite를 사용하여 반응 앱을 만드는 것을 선호합니다. 왜냐하면 create-react-app에 비해 실행 시간이 더 빠르기 때문입니다.
여기서는 vite의 템플릿으로 반응을 사용합니다.
자바스크립트 선택:
편집기에서 프로젝트를 엽니다. (이 프로젝트에서는 Vs 코드를 사용하겠습니다)
code .
src 디렉토리 안에 또 다른 디렉토리인 Hooks/useWebWorkers를 생성하세요.
이 폴더 안에 아래와 같이 웹 워커를 담을 index.js 파일을 생성하세요.
/hooks/useWebWorker/index.js 내에서 웹 워커를 생성하는 사용자 정의 후크를 생성합니다
workerFunction 및 inputData를 매개변수로 사용하는 useWebWorker 사용자 정의 후크를 만듭니다.
const useWebWorker =(workerFunction,inputData)=>{ } export default useWebWorker;
useState 후크를 사용하여 웹 작업자의 결과, 오류 및 상태에 대한 상태를 초기화합니다.
import {useState} from 'react' const useWebWorker =(workerFunction,inputData)=>{ const [result,setResult] = useState(null); const [error,setError] = useState(null); const [loading,setLoading] = useState(false); } export default useWebWorker;
i) result는 웹 워커의 결과를 저장합니다. 처음에는 null로 설정되어 있습니다.
ii)error는 웹 워커에서 발생할 수 있는 오류를 추적합니다. 초기에는 null로 설정됩니다.
iii) 로딩을 통해 웹 작업자의 상태가 데이터 처리 중인지 여부를 알 수 있습니다. 처음에는 false로 설정됩니다.
웹 작업자를 유지하기 위해 useEffect를 초기화합니다.
import {useState,useEffect} from 'react' const useWebWorker =(workerFunction,inputData)=>{ const [result,setResult] = useState(null); const [error,setError] = useState(null); const [loading,setLoading] = useState(false); useEffect(()=>{ },[inputData]) } export default useWebWorker;
useEffect 후크는 구분 기호로 설정되었기 때문에 inputData가 변경될 때마다 실행됩니다.
inputData가 null이거나 정의되지 않은 경우 후크가 일찍 종료됩니다.
if(!inputData)return;
모든 상태가 올바르게 재설정되었는지 확인하세요
setLoading(true); setError(null); setResult(null);
const blob = new Blob( [ ` self.onmessage = function(event) { (${workerFunction.toString()})(event); }; `, ], { type: "application/javascript" } );
workerFunction을 문자열로 변환하고 이를 Blob 객체에 포함합니다. 이 Blob은 Web Worker에서 실행될 JavaScript 코드를 나타냅니다.
Blob에 대한 URL을 생성하는 작업자를 생성하고 다음 URL을 사용하여 새 웹 작업자를 생성합니다.
const workerScriptUrl = URL.createObjectURL(blob); const worker = new Worker(workerScriptUrl);
작업자가 내보낸 메시지에 대한 이벤트 핸들러를 설정합니다.
worker.onmessage(event){ }
웹 작업자가 postMessage를 사용하여 메인 스레드에 메시지를 보내면 이벤트 핸들러가 트리거됩니다.
event.data에는 웹 작업자의 유효한 결과 또는 오류가 포함되어 있습니다. if-else 문 내에서 오류 또는 유효한 결과의 렌더링을 처리합니다.
오류가 발생하면 setError() 내부에서 event.data.error에 오류를 설정합니다.
유효한 결과가 반환되면 결과를 setResult()
내부의 event.data에 전달합니다.
worker.onmessage = (event) => { console.log("Worker result:", event.data); if (event.data.error) { setError(event.data.error); } else { setResult(event.data); } setLoading(false); };
완료되면 로딩을 false로 설정합니다.
worker.onerror(event)를 사용합니다{
}
이벤트를 매개변수로 전달하고 오류를 event.message로 업데이트하며 로딩 상태를 false로 업데이트합니다.
worker.onerror = (event) => { console.error("Worker error:", event.message); setError(event.message); setLoading(false); };
이제 inputData를 웹 작업자에게 보냅니다
worker.postMessage(inputData);
구성 요소가 마운트 해제되거나 inputData 또는 WorkerFunction이 변경되면 웹 작업자를 종료하고 Blob URL을 취소합니다.
return () => { worker.terminate(); URL.revokeObjectURL(workerScriptUrl); }; }, [inputData, workerFunction]);
결국 결과, 오류 및 로드 상태를 반환하여 웹 작업자의 상태를 반환합니다.
return {result,error,loading}
useWebWorker 내보내기:
export default useWebWorker;
다음은 Hooks/useWebWorker/index.js의 전체 코드입니다.
import { useState, useEffect } from "react"; const useWebWorker = (workerFunction, inputData) => { const [result, setResult] = useState(null); const [error, setError] = useState(null); const [loading, setLoading] = useState(false); useEffect(() => { if (!inputData) return; setLoading(true); setError(null); setResult(null); const blob = new Blob( [ ` self.onmessage = function(event) { (${workerFunction})(event); }; `, ], { type: "application/javascript" } ); const workerScriptUrl = URL.createObjectURL(blob); const worker = new Worker(workerScriptUrl); worker.onmessage = (event) => { console.log("Worker result:", event.data); setResult(event.data); setLoading(false); }; worker.onerror = (event) => { console.error("Worker error:", event.message); setError(event.message); setLoading(false); }; console.log("Posting message to worker:", inputData); worker.postMessage(inputData); return () => { worker.terminate(); URL.revokeObjectURL(workerScriptUrl); }; }, [inputData, workerFunction]); return { result, error, loading }; }; export default useWebWorker;
App.jsx에서 웹 작업자가 실행할 작업자 함수를 정의해 보겠습니다.
const workerFunction = (e) => { const { base, exponent } = e.data; console.log("Worker function received data:", base, exponent); let result = 1; for (let i = 0; i < exponent; i++) { result *= base; } self.postMessage(result); };
e.data contains data from the web worker.
The workerFunction:
Logs the received data (base and exponent).
Computes the power of base raised to exponent.
Sends the result back to the main thread using self.postMessage(result).
Let's now define our App functional component inside our App.jsx:
const App = () => { const [base, setBase] = useState(""); const [exponent, setExponent] = useState(""); const [inputData, setInputData] = useState(null); const { result, error, loading } = useWebWorker(workerFunction, inputData);
base: Stores the base number input.
exponent: Stores the exponent number input.
inputData: Stores the data to be sent to the worker.
Custom Hook Usage: useWebWorker is used to create a Web Worker and manage its state.
const handleBaseChange = (e) => setBase(e.target.value); const handleExponentChange = (e) => setExponent(e.target.value);
handleBaseChange: Updates base state when the input value changes.
handleExponentChange: Updates exponent state when the input value changes
const handleCalculate = () => { setInputData({ base: Number(base), exponent: Number(exponent) }); };
handleCalculate Function: Converts base and exponent to numbers and sets them as inputData for the Web Worker.
return ( <div> <h1>Exponential Calculation with Web Worker</h1> <div> <label> Base: <input type="number" value={base} onChange={handleBaseChange} /> </label> </div> <div> <label> Exponent: <input type="number" value={exponent} onChange={handleExponentChange} /> </label> </div> <button onClick={handleCalculate}>Calculate</button> {loading && <div>Loading...</div>} {error && <div>Error: {error}</div>} {!loading && !error && result !== null && <div>Result: {result}</div>} </div> ); };
JSX Layout:
Displays a title and input fields for base and exponent.
A button triggers the handleCalculate function.
Conditionally renders loading, error, or result messages based on the state.
Below is the complete App.jsx code:
import { useState } from "react"; import useWebWorker from "./hooks/useWebWorker"; import "./App.css"; const workerFunction = (e) => { const { base, exponent } = e.data; console.log("Worker function received data:", base, exponent); let result = 1; for (let i = 0; i < exponent; i++) { result *= base; } self.postMessage(result); }; const App = () => { const [base, setBase] = useState(""); const [exponent, setExponent] = useState(""); const [inputData, setInputData] = useState(null); const { result, error, loading } = useWebWorker(workerFunction, inputData); const handleBaseChange = (e) => setBase(e.target.value); const handleExponentChange = (e) => setExponent(e.target.value); const handleCalculate = () => { setInputData({ base: Number(base), exponent: Number(exponent) }); }; return ( <div> <h1>Exponential Calculation with Web Worker</h1> <div> <label> Base: <input type="number" value={base} onChange={handleBaseChange} /> </label> </div> <div> <label> Exponent: <input type="number" value={exponent} onChange={handleExponentChange} /> </label> </div> <button onClick={handleCalculate}>Calculate</button> {loading && <div>Loading...</div>} {error && <div>Error: {error}</div>} {!loading && !error && result !== null && <div>Result: {result}</div>} </div> ); }; export default App;
We can now use npm run dev to view our project.
Below is a live preview of our project:
Web Workers Project Implementation
Implementing Web Workers in your React applications can significantly enhance performance, especially when dealing with CPU-intensive tasks. By offloading such tasks to background threads, you ensure that your app remains responsive and provides a smooth user experience.
In our example, we've seen how straightforward it can be to set up and use Web Workers in a React environment. From dynamically creating a worker using a custom hook to managing the communication between the main thread and the worker, every step is designed to be both efficient and easy to integrate.
This approach not only helps in maintaining a responsive UI but also makes your app more robust and user-friendly. Whether it's for complex calculations, data processing, or any other heavy lifting, Web Workers can be your go-to solution for multitasking in modern web applications.
Remember, the key to a great user experience is not just about what your app does but how it feels while doing it. By implementing Web Workers, you can ensure that your app feels snappy and responsive, keeping your users happy and engaged. So, go ahead and explore the power of Web Workers in your next React project – your users will thank you for it!
위 내용은 React Hooks 애플리케이션의 백그라운드 처리를 위해 웹 작업자 활용.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!