Skip to content

Commit 2ea89cb

Browse files
committed
refactor: vocab lazy load.
1 parent 8b580eb commit 2ea89cb

File tree

7 files changed

+60
-44
lines changed

7 files changed

+60
-44
lines changed

src/components/MarkdownLink.js

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import React from 'react';
1+
import React, { Suspense, lazy } from 'react';
22
import { useSidePanel } from '../context/SidePanelContext';
33
import { vocabulary } from '../data/vocabulary';
4-
import { ArrowSquareOut } from '@phosphor-icons/react';
4+
import { ArrowSquareOut, CircleNotch } from '@phosphor-icons/react';
55

66
const MarkdownLink = ({ href, children, className, ...props }) => {
77
const { openSidePanel } = useSidePanel();
@@ -11,17 +11,29 @@ const MarkdownLink = ({ href, children, className, ...props }) => {
1111
if (isVocab) {
1212
const parts = href.split('/vocab/');
1313
const term = parts[1];
14-
const definition = vocabulary[term];
14+
const entry = vocabulary[term];
1515

1616
return (
1717
<a
1818
href={href}
1919
onClick={(e) => {
2020
e.preventDefault();
21-
if (definition) {
22-
openSidePanel(definition.title, definition.content);
21+
if (entry && entry.loader) {
22+
const LazyVocabComponent = lazy(entry.loader);
23+
openSidePanel(
24+
entry.title,
25+
<Suspense
26+
fallback={
27+
<div className="flex items-center justify-center p-8">
28+
<CircleNotch size={32} className="animate-spin text-gray-400" />
29+
</div>
30+
}
31+
>
32+
<LazyVocabComponent />
33+
</Suspense>
34+
);
2335
} else {
24-
console.warn(`Vocabulary term not found: ${term}`);
36+
console.warn(`Vocabulary term or loader not found: ${term}`);
2537
}
2638
}}
2739
className="text-pink-400 hover:text-pink-300 transition-colors inline-flex items-center gap-1 border-b border-pink-500/30 border-dashed hover:border-solid cursor-help"
@@ -46,4 +58,4 @@ const MarkdownLink = ({ href, children, className, ...props }) => {
4658
);
4759
};
4860

49-
export default MarkdownLink;
61+
export default MarkdownLink;

src/data/vocab/anti-pattern.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import React from 'react';
22

3-
export default {
4-
title: 'Anti-Pattern',
5-
content: (
3+
export default function AntiPattern() {
4+
return (
65
<div className="space-y-4">
76
<p>
87
An <strong>Anti-Pattern</strong> is a common response to a recurring problem that is usually ineffective and risks being highly counterproductive.
@@ -20,5 +19,5 @@ export default {
2019
</ul>
2120
</div>
2221
</div>
23-
),
24-
};
22+
);
23+
}

src/data/vocab/context-api.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import React from 'react';
22

3-
export default {
4-
title: 'Context API',
5-
content: (
3+
export default function ContextApi() {
4+
return (
65
<div className="space-y-4">
76
<p>
87
The <strong>Context API</strong> is a React feature that enables you to share values (like global settings, user auth, or themes) between components without having to explicitly pass a prop through every level of the tree.
98
</p>
109
</div>
11-
)
12-
};
10+
);
11+
}

src/data/vocab/pluribus.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import React from 'react';
22

3-
export default {
4-
title: 'Pluribus',
5-
content: (
3+
export default function Pluribus() {
4+
return (
65
<div className="space-y-4">
76
<p>
87
<strong>Pluribus</strong> is Latin for "from many" or "more". It is most famously known as part of the United States motto <em>E pluribus unum</em> ("Out of many, one").
@@ -16,5 +15,5 @@ export default {
1615
</p>
1716
</div>
1817
</div>
19-
),
20-
};
18+
);
19+
}

src/data/vocab/prop-drilling.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import React from 'react';
22

3-
export default {
4-
title: 'Prop Drilling',
5-
content: (
3+
export default function PropDrilling() {
4+
return (
65
<div className="space-y-4">
76
<p>
87
<strong>Prop Drilling</strong> (also known as "threading") refers to the process of passing data from a parent component down to a deeply nested child component through intermediate components that do not need the data themselves.
@@ -29,5 +28,5 @@ export default {
2928
<strong>Solution:</strong> Use the <em>Context API</em>, <em>Redux</em>, or similar state management libraries to make data accessible to any component in the tree without manual passing.
3029
</p>
3130
</div>
32-
),
33-
};
31+
);
32+
}

src/data/vocab/side-effects.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import React from 'react';
22

3-
export default {
4-
title: 'Side Effects',
5-
content: (
3+
export default function SideEffects() {
4+
return (
65
<div className="space-y-6">
76
<div>
87
<h4 className="flex items-center gap-2 text-sm font-bold text-purple-400 mb-2">
@@ -41,5 +40,5 @@ export default {
4140
</p>
4241
</div>
4342
</div>
44-
),
45-
};
43+
);
44+
}

src/data/vocabulary.js

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,22 @@
1-
import propDrilling from './vocab/prop-drilling';
2-
import contextApi from './vocab/context-api';
3-
import antiPattern from './vocab/anti-pattern';
4-
import pluribus from './vocab/pluribus';
5-
import sideEffects from './vocab/side-effects';
6-
71
export const vocabulary = {
8-
'prop-drilling': propDrilling,
9-
'context-api': contextApi,
10-
'anti-pattern': antiPattern,
11-
'pluribus': pluribus,
12-
'side-effects': sideEffects,
13-
};
2+
'prop-drilling': {
3+
title: 'Prop Drilling',
4+
loader: () => import('./vocab/prop-drilling'),
5+
},
6+
'context-api': {
7+
title: 'Context API',
8+
loader: () => import('./vocab/context-api'),
9+
},
10+
'anti-pattern': {
11+
title: 'Anti-Pattern',
12+
loader: () => import('./vocab/anti-pattern'),
13+
},
14+
'pluribus': {
15+
title: 'Pluribus',
16+
loader: () => import('./vocab/pluribus'),
17+
},
18+
'side-effects': {
19+
title: 'Side Effects',
20+
loader: () => import('./vocab/side-effects'),
21+
},
22+
};

0 commit comments

Comments
 (0)