add Higher-Order Components

This commit is contained in:
e560248
2025-04-08 11:52:10 +02:00
parent 22031864fb
commit 419113541b
6 changed files with 88 additions and 0 deletions

View File

@@ -10,6 +10,7 @@ import MemoCallbackPage from './pages/MemoCallbackPage'
import ComponentWrapperPage from './pages/ComponentWrapperPage'
import ZustandCounterPage from './pages/ZustandCounterPage'
import ModalPage from './pages/ModalPage'
import { HocPage } from './pages/HocPage'
function App() {
@@ -23,6 +24,7 @@ function App() {
<Route path="/componentwrapper" element={<ComponentWrapperPage />} />
<Route path="/modalpage" element={<ModalPage />} />
<Route path="/zustandcounterpage" element={<ZustandCounterPage />} />
<Route path="/hoc" element={<HocPage />} />
</Routes>
</MainLayout>
}

View File

@@ -10,6 +10,7 @@ export default function Navigation () {
<li><a href="/componentwrapper">Component Wrapper</a></li>
<li><a href="/modalpage">Modal</a></li>
<li><a href="/zustandcounterpage">ZustandCounterPage</a></li>
<li><a href="/hoc">HOC</a></li>
</ul>
</nav>);
}

View File

@@ -0,0 +1,18 @@
import withLoader, { LoaderData } from "./WithLoader";
import './DogImages.css';
interface DogImagesProps {
data: LoaderData;
}
function DogImages({data}: DogImagesProps) {
return data.message.map((img, index) => (
<img
key={index}
src={img}
className="dog-image"
/>
));
}
const DogImagesWithLoader = withLoader(DogImages, "https://dog.ceo/api/breed/labrador/images/random/6");
export default DogImagesWithLoader;

View File

@@ -0,0 +1,50 @@
import { ComponentType, useEffect, useState } from "react";
export type LoaderData = {
message: string[];
status: string;
}
interface WithLoaderProps {
data: LoaderData;
}
// HOC definition
export default function withLoader<P>(
WrappedComponent: ComponentType<P & WithLoaderProps>,
url: string,
) {
return function WithLoaderComponent(props: P) {
const [data, setData] = useState<LoaderData | null>(null);
useEffect(() => {
async function fetchData() {
try {
const response = await fetch(url);
const json = await response.json();
// setData(json);
setTimeout(() => {
setData(json);
}
, 5000);
}
catch (error) {
console.error("Error fetching data:", error);
}
}
fetchData();
}, []);
if (!data) {
return <p>Loading...</p>;
}
return (
<WrappedComponent {...(props as P)} data={data} />
);
};
}

View File

@@ -0,0 +1,6 @@
.dog-image {
width: 100px;
height: 100px;
border-radius: 50%;
margin: 10px;
}

View File

@@ -0,0 +1,11 @@
import ComponentWrapper from "../common/components/ComponentWrapper/ComponentWrapper";
import DogImagesWithLoader from "../common/components/exercises/HocExercise/DogImages";
export function HocPage() {
return (
<ComponentWrapper title="HOC Example">
<DogImagesWithLoader />
</ComponentWrapper>
)
}