Skip to content

Commit 473d665

Browse files
committed
memoization
1 parent d22c538 commit 473d665

12 files changed

Lines changed: 571 additions & 130 deletions

src/App.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import examplesUseState1 from "./examples/use-state-1";
44
import examplesUseEffect1 from "./examples/use-effect-1";
55
import examplesUseRef1 from "./examples/use-ref-1";
66
import examplesHooksOrder from "./examples/hooks-order";
7+
import examplesMemoization from "./examples/memoization";
78
import logo from "./logo.svg";
89
import ExampleBloc from "./commons/ExampleBloc";
910
import { IExample } from "./commons/types";
@@ -17,7 +18,8 @@ const App: React.FC = () => {
1718
.concat(examplesUseState1)
1819
.concat(examplesUseEffect1)
1920
.concat(examplesUseRef1)
20-
.concat(examplesHooksOrder);
21+
.concat(examplesHooksOrder)
22+
.concat(examplesMemoization);
2123

2224
return (
2325
<div className="App">
@@ -92,5 +94,4 @@ export default App;
9294
Idées:
9395
- pq utiliser un hook custom pour les contextes (permet d'éviter le typecheck sur null & co)
9496
- react context instantiation or mounting
95-
- hook component should never update
9697
*/

src/examples/hooks-order/ExampleUseState102.tsx

Lines changed: 0 additions & 73 deletions
This file was deleted.

src/examples/hooks-order/ExampleUseState103.tsx

Lines changed: 0 additions & 54 deletions
This file was deleted.
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import React from "react";
2+
import ActionButton from "../../commons/ActionButton";
3+
import { useLog } from "../../commons/ExampleBloc";
4+
import countPrimes from "./countPrimes";
5+
6+
const MyComponent = ({
7+
values,
8+
label
9+
}: {
10+
values: number[];
11+
label: string;
12+
}) => {
13+
const log = useLog();
14+
15+
log("Before countPrimes");
16+
const primes = countPrimes(values);
17+
log("After countPrimes");
18+
19+
return (
20+
<>
21+
Primes in {label}: {primes}
22+
</>
23+
);
24+
};
25+
26+
const ExampleMemoization101 = () => {
27+
const log = useLog();
28+
29+
const [values, setValues] = React.useState<number[]>([]);
30+
const [label, setLabel] = React.useState<string>("my-label");
31+
log("virtual-render", { valuesLength: values.length, label });
32+
33+
return (
34+
<>
35+
<pre>
36+
{JSON.stringify({ valuesLength: values.length, label }, null, 2)}
37+
</pre>
38+
<div>
39+
<MyComponent values={values} label={label} />
40+
</div>
41+
<ul>
42+
<li>
43+
<ActionButton
44+
label="Generate random values"
45+
onClick={() => {
46+
let values = [];
47+
for (let i = 0; i < 1000000; i++) {
48+
values.push(Math.floor(Math.random() * 1000000));
49+
}
50+
setValues(values);
51+
}}
52+
/>
53+
</li>
54+
<li>
55+
<ActionButton
56+
label="Randomize label"
57+
onClick={() => {
58+
setLabel(
59+
Math.random()
60+
.toString(36)
61+
.substr(2, 5)
62+
);
63+
}}
64+
/>
65+
</li>
66+
</ul>
67+
</>
68+
);
69+
};
70+
71+
export default ExampleMemoization101;
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import React from "react";
2+
import ActionButton from "../../commons/ActionButton";
3+
import { useLog } from "../../commons/ExampleBloc";
4+
import countPrimes from "./countPrimes";
5+
6+
const MyComponent = ({
7+
values,
8+
label
9+
}: {
10+
values: number[];
11+
label: string;
12+
}) => {
13+
const log = useLog();
14+
15+
const ref = React.useRef<{ previousValues: number[]; primes: number }>();
16+
17+
// Cache invalidation
18+
if (ref.current && ref.current.previousValues !== values) {
19+
ref.current = undefined;
20+
}
21+
22+
// Cache computation
23+
if (!ref.current) {
24+
log("Before countPrimes");
25+
const primes = countPrimes(values);
26+
log("After countPrimes");
27+
ref.current = {
28+
// We need to track the previous parameters
29+
previousValues: values,
30+
primes
31+
};
32+
}
33+
34+
return (
35+
<>
36+
Primes in {label}: {ref.current && ref.current.primes}
37+
</>
38+
);
39+
};
40+
41+
const ExampleMemoization102 = () => {
42+
const log = useLog();
43+
44+
const [values, setValues] = React.useState<number[]>([]);
45+
const [label, setLabel] = React.useState<string>("my-label");
46+
log("virtual-render", { valuesLength: values.length, label });
47+
48+
return (
49+
<>
50+
<pre>
51+
{JSON.stringify({ valuesLength: values.length, label }, null, 2)}
52+
</pre>
53+
<div>
54+
<MyComponent values={values} label={label} />
55+
</div>
56+
<ul>
57+
<li>
58+
<ActionButton
59+
label="Generate random values"
60+
onClick={() => {
61+
let values = [];
62+
for (let i = 0; i < 1000000; i++) {
63+
values.push(Math.floor(Math.random() * 1000000));
64+
}
65+
setValues(values);
66+
}}
67+
/>
68+
</li>
69+
<li>
70+
<ActionButton
71+
label="Randomize label"
72+
onClick={() => {
73+
setLabel(
74+
Math.random()
75+
.toString(36)
76+
.substr(2, 5)
77+
);
78+
}}
79+
/>
80+
</li>
81+
</ul>
82+
</>
83+
);
84+
};
85+
86+
export default ExampleMemoization102;
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import React from "react";
2+
import ActionButton from "../../commons/ActionButton";
3+
import { useLog } from "../../commons/ExampleBloc";
4+
import countPrimes from "./countPrimes";
5+
6+
const MyComponent = ({
7+
values,
8+
label
9+
}: {
10+
values: number[];
11+
label: string;
12+
}) => {
13+
const log = useLog();
14+
15+
const primes = React.useMemo(() => {
16+
log("Before countPrimes");
17+
const primes = countPrimes(values);
18+
log("After countPrimes");
19+
return primes;
20+
}, [values, log]);
21+
22+
return (
23+
<>
24+
Primes in {label}: {primes}
25+
</>
26+
);
27+
};
28+
29+
const ExampleMemoization103 = () => {
30+
const log = useLog();
31+
32+
const [values, setValues] = React.useState<number[]>([]);
33+
const [label, setLabel] = React.useState<string>("my-label");
34+
log("virtual-render", { valuesLength: values.length, label });
35+
36+
return (
37+
<>
38+
<pre>
39+
{JSON.stringify({ valuesLength: values.length, label }, null, 2)}
40+
</pre>
41+
<div>
42+
<MyComponent values={values} label={label} />
43+
</div>
44+
<ul>
45+
<li>
46+
<ActionButton
47+
label="Generate random values"
48+
onClick={() => {
49+
let values = [];
50+
for (let i = 0; i < 1000000; i++) {
51+
values.push(Math.floor(Math.random() * 1000000));
52+
}
53+
setValues(values);
54+
}}
55+
/>
56+
</li>
57+
<li>
58+
<ActionButton
59+
label="Randomize label"
60+
onClick={() => {
61+
setLabel(
62+
Math.random()
63+
.toString(36)
64+
.substr(2, 5)
65+
);
66+
}}
67+
/>
68+
</li>
69+
</ul>
70+
</>
71+
);
72+
};
73+
74+
export default ExampleMemoization103;

0 commit comments

Comments
 (0)