Skip to content

Commit 3b4323c

Browse files
committed
[WIP] LazyComponent
1 parent ba66305 commit 3b4323c

4 files changed

Lines changed: 36 additions & 10 deletions

File tree

apps/react-tools-demo/src/assets/bubbles.mp3:Zone.Identifier

Whitespace-only changes.

apps/react-tools-demo/src/markdown/useStateValidator.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,29 +11,29 @@ export const UseStateValidator = () => {
1111
},
1212
(state, validation) => {
1313
if (state.name.length > 10) {
14-
validation.name.result = false;
14+
validation.name.invalid = true;
1515
validation.name.message = "Max Length 10 characters"
1616
}
1717
if (!state.email.includes("@")) {
18-
validation.email.result = false;
18+
validation.email.invalid = true;
1919
validation.email.message = "@ is missing"
2020
}
2121
return validation;
2222
}
2323
);
2424

2525
return <div>
26-
<div>
26+
<div style={{display: "flex", flexDirection: "column", width: 'fit-content', margin: "0 auto"}}>
2727
<input type="text" name="name" value={state.name} onChange={e => setState(s => ({...s, [e.target.name]: e.target.value}))} />
2828
{
29-
validation.name.result &&
29+
validation.name.invalid &&
3030
<span style={{ color: "red" }}>{validation.name.message}</span>
3131
}
3232
</div>
33-
<div>
33+
<div style={{display: "flex", flexDirection: "column", width: 'fit-content', margin: "0 auto"}}>
3434
<input type="text" name="email" value={state.email} onChange={e => setState(s => ({...s, [e.target.name]: e.target.value}))} />
3535
{
36-
validation.email.result &&
36+
validation.email.invalid &&
3737
<span style={{ color: "red" }}>{validation.email.message}</span>
3838
}
3939
</div>
@@ -47,7 +47,7 @@ export const UseStateValidator = () => {
4747
## API
4848

4949
```tsx
50-
useStateValidator<T>(initialState: T | (() => T), validator: StateValidator<T>): [T, Dispatch<SetStateAction<T>>, T extends Record<string, unknown> ? {[k in keyof T]:{result: boolean, message?: string}} : {result: boolean, message?: string}]
50+
useStateValidator<T>(initialState: T | (() => T), validator: StateValidator<T>): [T, Dispatch<SetStateAction<T>>, T extends Record<string, unknown> ? {[k in keyof T]:{invalid: boolean, message?: string}} : {invalid: boolean, message?: string}]
5151
```
5252

5353
> ### Params
@@ -60,10 +60,10 @@ function that will be executed to validate state.
6060
6161
> ### Returns
6262
>
63-
> __} result__: __Array__:
63+
> __} invalid__: __Array__:
6464
- _T_
6565
- _Dispatch<SetStateAction<T>>_
66-
- _T extends Record<string, unknown> ? {[k in keyof T]:{result: boolean, message?: string}} : {result: boolean, message?: strin_
66+
- _T extends Record<string, unknown> ? {[k in keyof T]:{invalid: boolean, message?: string}} : {invalid: boolean, message?: strin_
6767
> Array with:
6868
> - first element: __state__ value.
6969
> - second element: __setState__ function to update state.

packages/react-tools/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,8 @@
155155
- [ ] Index: Non-keyed list iteration (rendered nodes are keyed to an array index). This is useful when there is no conceptual key, like if the data consists of primitives and it is the index that is fixed rather than the value.
156156
- [ ] RestrictedRoute (maybe)
157157
- [ ] ErrorBoundary (?? error event listener)
158-
- [ ] Suspense: Suspence compontent react-like for async component
158+
- [ ] LazyComponent: Async component loading by path and fallback for suspense
159+
- [ ] Suspense: Suspence compontent react-like for async component (or polyfill)
159160
- [ ] Dynamic: This component lets you insert an arbitrary Component or tag and passes the props through to it.
160161
- [ ] ImageOpt (???)
161162

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { Suspense, JSX } from "react";
2+
3+
const promise: { name: string; promise: Promise<void>; response?:()=>JSX.Element }[] = [];
4+
const DynamicComponent = ({ name }: { name: string }) => {
5+
for (const prom of promise) {
6+
if (prom.name === name) {
7+
return prom.response && prom.response();
8+
}
9+
}
10+
11+
const current: typeof promise[number] = {
12+
name,
13+
promise: import(`../components/hooks/${name}/${name.charAt(0).toUpperCase() + name.substring(1)}.tsx`).then((res) => {
14+
current.response = res[name.charAt(0).toUpperCase() + name.substring(1)]
15+
}),
16+
}
17+
promise.push(current);
18+
throw current.promise;
19+
};
20+
21+
const LazyComponent = ({ name }: { name: string }) => {
22+
return <Suspense fallback="loading">
23+
<DynamicComponent name={name} />
24+
</Suspense>
25+
}

0 commit comments

Comments
 (0)