Skip to content

Commit 4580a09

Browse files
committed
useRef103
1 parent 6db94b1 commit 4580a09

5 files changed

Lines changed: 98 additions & 14 deletions

File tree

src/App.css

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,6 @@
88
pointer-events: none;
99
}
1010

11-
.App-header {
12-
background-color: #282c34;
13-
min-height: 100vh;
14-
display: flex;
15-
flex-direction: column;
16-
align-items: center;
17-
justify-content: center;
18-
font-size: calc(10px + 2vmin);
19-
color: white;
20-
}
21-
2211
.App-link {
2312
color: #61dafb;
2413
}

src/App.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ const App: React.FC = () => {
4646
<h4>Examples:</h4>
4747
<ul>
4848
{examples.map(example => (
49-
<li style={{}}>
49+
<li key={example.title} style={{}}>
5050
<a
5151
href={`#${genId(example.title)}`}
5252
style={{ textDecoration: "none", color: "#61dafb" }}

src/commons/ExampleBloc/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ const ComponentAndText = ({
109109
right: 0
110110
}}
111111
>
112-
<Preface>{preface}</Preface>
112+
{preface && <Preface>{preface}</Preface>}
113113
<div
114114
style={{
115115
padding: 10,
@@ -121,7 +121,7 @@ const ComponentAndText = ({
121121
>
122122
{children}
123123
</div>
124-
<Explanation>{explanation}</Explanation>
124+
{explanation && <Explanation>{explanation}</Explanation>}
125125
</div>
126126
);
127127
};
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import React from "react";
2+
import ActionButton from "../../commons/ActionButton";
3+
import { useLog } from "../../commons/ExampleBloc";
4+
5+
const MyComponent = ({ value }: { value: number }) => {
6+
return <pre>Number inside MyComponent: {value}</pre>;
7+
};
8+
9+
function renderOnce<P extends object>(
10+
Component: React.ComponentType<P>
11+
): React.FC<P> {
12+
return function HocComponent(props: P) {
13+
const ref = React.useRef<React.ReactElement | null>(null);
14+
15+
if (ref.current === null) {
16+
ref.current = <Component {...props} />;
17+
}
18+
19+
return ref.current ? ref.current : null;
20+
};
21+
}
22+
23+
const RenderOnceMyComponent = renderOnce(MyComponent);
24+
25+
const ExampleUseRef103 = () => {
26+
const log = useLog();
27+
28+
const [state, setState] = React.useState<number>(0);
29+
log("virtual-render", { state });
30+
31+
return (
32+
<>
33+
<pre>Number outside MyComponent: {state}</pre>
34+
35+
<div>
36+
<RenderOnceMyComponent value={state} />
37+
</div>
38+
39+
<ul>
40+
<li>
41+
<ActionButton
42+
label="Do nothing state-wise"
43+
onClick={() => {
44+
/* NOOP */
45+
}}
46+
/>
47+
</li>
48+
<li>
49+
<ActionButton
50+
label="Increment"
51+
onClick={() => {
52+
setState(state + 1);
53+
}}
54+
/>
55+
</li>
56+
<li>
57+
<ActionButton
58+
label="Reset to 0"
59+
onClick={() => {
60+
setState(0);
61+
}}
62+
/>
63+
</li>
64+
</ul>
65+
</>
66+
);
67+
};
68+
69+
export default ExampleUseRef103;

src/examples/use-ref-1/index.tsx

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,15 @@
22
import ExampleUseRef101Code from "!raw-loader!./ExampleUseRef101";
33
/* eslint import/no-webpack-loader-syntax: off */
44
import ExampleUseRef102Code from "!raw-loader!./ExampleUseRef102";
5+
/* eslint import/no-webpack-loader-syntax: off */
6+
import ExampleUseRef103Code from "!raw-loader!./ExampleUseRef103";
57
import React from "react";
8+
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
9+
import highlightStyle from "react-syntax-highlighter/dist/esm/styles/prism/tomorrow";
610
import { IExample } from "../../commons/types";
711
import ExampleUseRef101 from "./ExampleUseRef101";
812
import ExampleUseRef102 from "./ExampleUseRef102";
13+
import ExampleUseRef103 from "./ExampleUseRef103";
914

1015
const examples: IExample[] = [
1116
{
@@ -40,7 +45,28 @@ const examples: IExample[] = [
4045
a re-render when called. This way, we are able to display the content of
4146
the ref.
4247
</>
48+
),
49+
explanation: (
50+
<>
51+
Exercise for the reader: build a HOC (Higher Order Component) that mount
52+
a component once and will never trigger a new render.
53+
<br />
54+
It should look like this:
55+
<SyntaxHighlighter
56+
customStyle={{}}
57+
language="typescript"
58+
style={highlightStyle}
59+
>
60+
const RenderOnceMyComponent = renderOnce(MyComponent);
61+
</SyntaxHighlighter>
62+
</>
4363
)
64+
},
65+
{
66+
title: "useRef 103",
67+
Component: ExampleUseRef103,
68+
code: ExampleUseRef103Code,
69+
preface: <>Solution to the exercise</>
4470
}
4571
];
4672

0 commit comments

Comments
 (0)