Skip to content

Commit b2e8b1f

Browse files
committed
[FIX] For component
1 parent 714fa25 commit b2e8b1f

131 files changed

Lines changed: 235 additions & 198 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

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

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,36 +4,46 @@ Component to optimize the rendering of a list of elements without need to specif
44
## Usage
55

66
```tsx
7+
const Paragraph = memo(({ index, firstName, lastName }: { index: string, firstName: string, lastName: string }) => {
8+
console.log("P render");
9+
return <p>{index}: {firstName} - {lastName}</p>
10+
})
11+
712
export default function ForComponent() {
8-
const arr = useRef([
9-
{ id: "1", firstName: "Jhon", lastName: "Doe" },
10-
{ id: "2", firstName: "Jona", lastName: "Doe" },
11-
{ id: "3", firstName: "Jhonney", lastName: "Doe" }
13+
const [arr, setArr] = useState([
14+
{ id: "1", firstName: "firstName1", lastName: "lastName1" },
15+
{ id: "2", firstName: "firstName2", lastName: "lastName2" },
16+
{ id: "3", firstName: "firstName3", lastName: "lastName3" }
1217
]);
13-
const [, update] = useReducer(t => !t, false);
14-
15-
const body = useCallback<(item: { id: string, firstName: string, lastName: string }, index: number|string) => JSX.Element>((item, index) => {
16-
console.log("body render");
17-
return <p>{index}: {item.firstName} - {item.lastName}</p>
18-
}, []);
1918

2019
useEffect(() => {
21-
const id = setInterval(() => update(), 1000);
22-
return () => clearInterval(id)
20+
const id2 = setInterval(() => {
21+
setArr(a => {
22+
const added = Math.random() > 0.5;
23+
console.log(added ? "added" : "removed");
24+
const id = Math.max(...[0, ...a.map(el => Number(el.id))])+1
25+
return added
26+
? [{ id: "" + id, firstName: "firstName" + id, lastName: "lastName" + id }, ...a]
27+
: a.filter((_, index) => index !== 0)
28+
})
29+
}, 3500);
30+
return () => {
31+
clearInterval(id2)
32+
}
2333
}, [])
2434

2535
return <>
2636
<For
37+
of={arr}
2738
elementKey="id"
28-
of={arr.current}
2939
>
30-
{body}
40+
{(item, _, key) => <Paragraph index={key as string} firstName={item.firstName} lastName={item.lastName} />}
3141
</For>
3242
</>
3343
}
3444
```
3545

36-
> The component uses _For_ component to render a p element returned from _body_ memoized function for all objects assigned to _arr_ ref variable. It also specified __id__ property as _elementKey_ prop. A setInverval is executed on mount that on every second force component to rerender. If you open dev tools, you can see that _body_ function logs only three times at first, one for each element of _arr_ variable
46+
> The component has a _arr_ array state variable of objects that every 3 seconds added or removed an element. It uses _For_ component to iterate _arr_ and to render the memoized _Paragraph_ component, specifing __id__ element property as _elementKey_ prop. _Paragraph_ component logs in console a message before return the tag p. If you open dev tools, you can see that message is displayed only three times at first, and once when an element is added to _arr_ variable.
3747
3848

3949
## API
@@ -48,18 +58,18 @@ For = memo(<T extends unknown>({ of, children, filter, map, sort, elementKey, fa
4858
component properties object.
4959
> - __props.of__: _T[]_
5060
array of elements.
51-
> - __props.elementKey?__: _T extends object ? keyof T | ((item: T) => string | number) : string | number | ((item: T) => string | number)_
52-
if the elements are objects, this prop is a key of the array elements or a function with one parameter which type is the type of the elements in __of__ prop and returns a string or a number, otherwise this prop can be the function described before, a string or a number.
53-
> - __props.children__: _(item: T, index: T extends object ? number | T[keyof T] | string : number) => ReactNode_
54-
it's a function that takes the current item as first argument and optionally a second argument that is number if element of array aren't object, otherwise it can be a number or the value of the element key specified in the _elementKey_ prop.
61+
> - __props.elementKey?__: _T extends object ? keyof T | ((item: T) => Key) : Key | ((item: T) => Key)_
62+
if the elements are objects, this prop can be a key of the elements in __of__ prop, or a function with one parameter which type is the type of the elements in __of__ prop and returns a __React.Key__ type, otherwise this prop can be the function described before or a __React.Key__. If it isn't specified, element index in __of__ props will be used as key.
63+
> - __props.children__: _(item: T, index: number, key: Key) => ReactNode_
64+
it's a function that takes the current item as first argument and optionally a second argument that is the index of element in _of_ prop and a third element that is the key specified in the _elementKey_ prop.
5565
> - __props.fallback?__: _ReactNode_
5666
optional element to render when _of_ prop is an empty array.
5767
> - __props.filter?__: _<S extends T>(val: T, index: number, arr: T[]) => val is S_
5868
callback executed to filter _of_ elements.
5969
> - __props.map?__: _<U extends T>(val: T, index: number, arr: T[]) => U_
6070
callback executed to map _of_ elements.
61-
> - __props.sort?__: _(a: T, b: T) => number_
62-
callback executed to sort _of_ elements.
71+
> - __props.sort?__: _true | ((a: T, b: T) => number)_
72+
callback executed to sort _of_ elements or __`true`__ to use native sort.
6373
>
6474

6575

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,43 @@
1-
import { useCallback, useEffect, useReducer, useRef } from "react";
1+
import { memo, useEffect, useState } from "react";
22
import { For } from "../../../../../../packages/react-tools-lib/src";
33

44
/**
5-
The component uses _For_ component to render a p element returned from _body_ memoized function for all objects assigned to _arr_ ref variable. It also specified __id__ property as _elementKey_ prop. A setInverval is executed on mount that on every second force component to rerender. If you open dev tools, you can see that _body_ function logs only three times at first, one for each element of _arr_ variable
5+
The component has a _arr_ array state variable of objects that every 3 seconds added or removed an element. It uses _For_ component to iterate _arr_ and to render the memoized _Paragraph_ component, specifing __id__ element property as _elementKey_ prop. _Paragraph_ component logs in console a message before return the tag p. If you open dev tools, you can see that message is displayed only three times at first, and once when an element is added to _arr_ variable.
66
*/
7+
const Paragraph = memo(({ index, firstName, lastName }: { index: string, firstName: string, lastName: string }) => {
8+
console.log("P render");
9+
return <p>{index}: {firstName} - {lastName}</p>
10+
})
11+
712
export default function ForComponent() {
8-
const arr = useRef([
9-
{ id: "1", firstName: "Jhon", lastName: "Doe" },
10-
{ id: "2", firstName: "Jona", lastName: "Doe" },
11-
{ id: "3", firstName: "Jhonney", lastName: "Doe" }
13+
const [arr, setArr] = useState([
14+
{ id: "1", firstName: "firstName1", lastName: "lastName1" },
15+
{ id: "2", firstName: "firstName2", lastName: "lastName2" },
16+
{ id: "3", firstName: "firstName3", lastName: "lastName3" }
1217
]);
13-
const [, update] = useReducer(t => !t, false);
14-
15-
const body = useCallback<(item: { id: string, firstName: string, lastName: string }, index: number|string) => JSX.Element>((item, index) => {
16-
console.log("body render");
17-
return <p>{index}: {item.firstName} - {item.lastName}</p>
18-
}, []);
1918

2019
useEffect(() => {
21-
const id = setInterval(() => update(), 1000);
22-
return () => clearInterval(id)
20+
const id2 = setInterval(() => {
21+
setArr(a => {
22+
const added = Math.random() > 0.5;
23+
console.log(added ? "added" : "removed");
24+
const id = Math.max(...[0, ...a.map(el => Number(el.id))])+1
25+
return added
26+
? [{ id: "" + id, firstName: "firstName" + id, lastName: "lastName" + id }, ...a]
27+
: a.filter((_, index) => index !== 0)
28+
})
29+
}, 3500);
30+
return () => {
31+
clearInterval(id2)
32+
}
2333
}, [])
2434

2535
return <>
2636
<For
37+
of={arr}
2738
elementKey="id"
28-
of={arr.current}
2939
>
30-
{body}
40+
{(item, _, key) => <Paragraph index={key as string} firstName={item.firstName} lastName={item.lastName} />}
3141
</For>
3242
</>
3343
}
Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/assets/For-Qlez-Cwr.js

Lines changed: 0 additions & 1 deletion
This file was deleted.

docs/assets/For-_P7G_6P8.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)