├── .gitignore
├── .prettierrc
├── README.md
├── deck.mdx
├── netlify.toml
├── onemorething.jpg
├── package-lock.json
├── package.json
└── src
├── context.js
├── greeting-loader.js
├── greeting.1.1.js
├── greeting.class.1.1.js
├── greeting.class.1.2.js
├── greeting.class.1.3.js
├── greeting.class.2.1.js
├── greeting.class.3.1.js
├── greeting.class.3.2.js
├── greeting.class.3.3.js
├── greeting.class.4.1.js
├── greeting.class.5.1.js
├── greeting.class.5.2.js
├── greeting.class.5.3.js
├── greeting.class.5.4.js
├── greeting.hooks.1.1.js
├── greeting.hooks.1.2.js
├── greeting.hooks.1.3.js
├── greeting.hooks.1.4.js
├── greeting.hooks.2.1.js
├── greeting.hooks.3.1.js
├── greeting.hooks.3.2.js
├── greeting.hooks.3.3.js
├── greeting.hooks.4.1.js
├── greeting.hooks.4.2.js
├── greeting.hooks.5.1.js
├── greeting.hooks.5.2.js
├── greeting.hooks.5.3.js
├── greeting.hooks.6.1.js
├── greeting.hooks.6.2.js
├── greeting.hooks.6.3.js
├── row.js
└── styles.css
/.gitignore:
--------------------------------------------------------------------------------
1 | dist
2 | node_modules
3 | public
4 | .cache
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "trailingComma": "es5",
3 | "printWidth": 60
4 | }
5 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # MDX Deck + Code Surfer template
2 |
3 | This project was generated with the `npm init code-surfer-deck` command.
4 |
5 | ## Development
6 |
7 | To run the presentation deck in development mode:
8 |
9 | ```sh
10 | npm start
11 | ```
12 |
13 | Edit the [`deck.mdx`](deck.mdx) file to get started.
14 |
15 | ## Exporting
16 |
17 | To build the presentation deck:
18 |
19 | ```sh
20 | npm run build
21 | ```
22 |
23 | For more documentation see [MDX Deck](https://github.com/jxnblk/mdx-deck) and [Code Surfer](https://codesurfer.pomb.us/)
24 |
--------------------------------------------------------------------------------
/deck.mdx:
--------------------------------------------------------------------------------
1 | import { Image, Notes, Head } from "mdx-deck";
2 | import { CodeSurferColumns, Step } from "code-surfer";
3 | import {
4 | vsDark as classTheme,
5 | nightOwl as hooksTheme,
6 | } from "@code-surfer/themes";
7 |
8 | import GreetingLoader from "./src/greeting-loader";
9 | import onemorething from "./onemorething.jpg";
10 |
11 | export const theme = classTheme;
12 |
13 |
14 | React Hooks Intro
15 |
16 |
17 | This is a copy of [Dan's hooks demo](https://youtu.be/dpw9EHDh2bM?t=1051) from React Conf
18 |
19 | I built it to test [Code Surfer v3](https://codesurfer.pomb.us/)
20 |
21 | ---
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | ```jsx file=./src/greeting.1.1.js
30 | ```
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | ```jsx 7 file=./src/greeting.1.1.js
39 | ```
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | ```jsx file=./src/greeting.class.1.1.js
48 | ```
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | ```jsx file=./src/greeting.class.1.2.js
57 | ```
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 | ```jsx 10:12,15:17,25 file=./src/greeting.class.1.3.js
66 | ```
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | ```jsx 1:31 file=./src/greeting.class.1.3.js
75 | ```
76 |
77 |
78 |
79 |
80 |
81 | ---
82 |
83 | But let's take a step back
84 |
85 | ---
86 |
87 |
91 |
92 |
93 |
94 |
95 |
96 | ```jsx file=./src/greeting.1.1.js
97 | ```
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 | ```jsx 5,10 file=./src/greeting.hooks.1.1.js
106 | ```
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 | ```jsx 5 file=./src/greeting.hooks.1.1.js
115 | ```
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 | ```jsx 6,8:10,15[29:55] file=./src/greeting.hooks.1.2.js
124 | ```
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 | ```jsx 5:6 file=./src/greeting.hooks.1.2.js
133 | ```
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 | ```jsx file=./src/greeting.hooks.1.3.js
142 | ```
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 | ```jsx 1[15:40],5 file=./src/greeting.hooks.1.4.js
151 | ```
152 |
153 |
154 |
155 |
156 |
157 | ---
158 |
159 |
160 |
161 |
162 |
163 | ```jsx file=./src/greeting.class.1.3.js title="Before Hooks" subtitle="A class component with state"
164 | ```
165 |
166 | ```jsx file=./src/greeting.hooks.1.4.js title="After Hooks" subtitle="A function component with state"
167 | ```
168 |
169 |
170 |
171 |
172 |
173 | ```jsx 7:9 file=./src/greeting.class.1.3.js title="Before Hooks" subtitle="state has to be an object"
174 | ```
175 |
176 | ```jsx 5 file=./src/greeting.hooks.1.4.js title="After Hooks" subtitle="state could be anything"
177 | ```
178 |
179 |
180 |
181 |
182 |
183 | ```jsx 7:12,16,24 file=./src/greeting.class.1.3.js title="Before Hooks" subtitle="we read and update the state using this.state and this.setState"
184 | ```
185 |
186 | ```jsx 5,8,14[16:27] file=./src/greeting.hooks.1.4.js title="After Hooks" subtitle="the state and the setter are just variables in the function"
187 | ```
188 |
189 |
190 |
191 |
192 |
193 | ```jsx 1[100],31[100] file=./src/greeting.class.1.3.js title="Before Hooks"
194 | ```
195 |
196 | ```jsx 1[1:7,15:40],5 file=./src/greeting.hooks.1.4.js title="After Hooks"
197 | ```
198 |
199 |
200 |
201 |
202 |
203 | ---
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 | ```jsx file=./src/greeting.class.1.3.js
212 | ```
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 | ```jsx file=./src/greeting.class.2.1.js
221 | ```
222 |
223 |
224 |
225 |
226 |
227 | ---
228 |
229 |
233 |
234 |
235 |
236 |
237 |
238 | ```jsx file=./src/greeting.hooks.1.4.js
239 | ```
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 | ```jsx file=./src/greeting.hooks.2.1.js
248 | ```
249 |
250 |
251 |
252 |
253 |
254 | ---
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 | ```jsx file=./src/greeting.class.2.1.js
263 | ```
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 | ```jsx file=./src/greeting.class.3.1.js
272 | ```
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 | ```jsx 30,31,32[20:37],46,47 file=./src/greeting.class.3.2.js
281 | ```
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 | ```jsx file=./src/greeting.class.3.3.js
290 | ```
291 |
292 |
293 |
294 |
295 |
296 | ---
297 |
298 |
302 |
303 |
304 |
305 |
306 |
307 | ```jsx file=./src/greeting.hooks.2.1.js
308 | ```
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 | ```jsx 1[27:37,40:52],3 file=./src/greeting.hooks.3.1.js
317 | ```
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 | ```jsx 8,19[14:30] file=./src/greeting.hooks.3.2.js
326 | ```
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 | ```jsx file=./src/greeting.hooks.3.3.js
335 | ```
336 |
337 |
338 |
339 |
340 |
341 | ---
342 |
343 |
344 |
345 |
346 |
347 | ```jsx 30,31,45,46,48,49,51,52 file=./src/greeting.class.3.3.js title="Before Hooks"
348 | ```
349 |
350 | ```jsx 8,9 file=./src/greeting.hooks.3.3.js title="After Hooks"
351 | ```
352 |
353 |
354 |
355 |
356 |
357 | ---
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 | ```jsx file=./src/greeting.class.3.3.js
366 | ```
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 | ```jsx file=./src/greeting.class.4.1.js
375 | ```
376 |
377 |
378 |
379 |
380 |
381 | ---
382 |
383 |
387 |
388 |
389 |
390 |
391 |
392 | ```jsx file=./src/greeting.hooks.3.3.js
393 | ```
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 | ```jsx 1,4,5 file=./src/greeting.hooks.4.1.js
402 | ```
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 | ```jsx file=./src/greeting.hooks.4.2.js
411 | ```
412 |
413 |
414 |
415 |
416 |
417 | ---
418 |
419 |
420 |
421 |
422 |
423 | ```jsx 20:28 file=./src/greeting.class.4.1.js title="Before Hooks" subtitle="We have different lifecycle methods for mount and update"
424 | ```
425 |
426 | ```jsx 15:17 file=./src/greeting.hooks.4.2.js title="After Hooks"
427 | ```
428 |
429 |
430 |
431 |
432 |
433 | ```jsx 20:28 file=./src/greeting.class.4.1.js title="Before Hooks" subtitle="we use this.state to access state"
434 | ```
435 |
436 | ```jsx 15:17 file=./src/greeting.hooks.4.2.js title="After Hooks" subtitle="the effect is inside the function component so we can use the variables from the function scope"
437 | ```
438 |
439 |
440 |
441 |
442 |
443 | ---
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 | ```jsx file=./src/greeting.class.4.1.js
452 | ```
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 | ```jsx file=./src/greeting.class.5.1.js
461 | ```
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 | ```jsx file=./src/greeting.class.5.2.js
470 | ```
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 | ```jsx file=./src/greeting.class.5.3.js
479 | ```
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 | ```jsx file=./src/greeting.class.5.4.js
488 | ```
489 |
490 |
491 |
492 |
493 |
494 | ---
495 |
496 |
500 |
501 |
502 |
503 |
504 |
505 | ```jsx file=./src/greeting.hooks.4.2.js
506 | ```
507 |
508 |
509 |
510 |
511 |
512 |
513 |
514 | ```jsx file=./src/greeting.hooks.5.1.js
515 | ```
516 |
517 |
518 |
519 |
520 |
521 |
522 |
523 | ```jsx file=./src/greeting.hooks.5.2.js
524 | ```
525 |
526 |
527 |
528 |
529 |
530 |
531 |
532 | ```jsx 20,23:26 file=./src/greeting.hooks.5.3.js
533 | ```
534 |
535 |
536 |
537 |
538 |
539 | ---
540 |
541 |
542 |
543 |
544 |
545 | ```jsx 22:35 file=./src/greeting.class.5.4.js title="Before Hooks" subtitle="the logic for the different effects is mixed and splitted apart in different methods"
546 | ```
547 |
548 | ```jsx 15:17,20:26 file=./src/greeting.hooks.5.3.js title="After Hooks" subtitle="the code is separated based on what is doing instead of when it runs"
549 | ```
550 |
551 |
552 |
553 |
554 |
555 | ---
556 |
557 |
558 |
559 | ---
560 |
561 |
565 |
566 |
567 |
568 |
569 |
570 | ```jsx 1:51 file=./src/greeting.hooks.5.3.js
571 | ```
572 |
573 |
574 |
575 |
576 |
577 |
578 |
579 | ```jsx 19:26 file=./src/greeting.hooks.5.3.js
580 | ```
581 |
582 |
583 |
584 |
585 |
586 |
587 |
588 | ```jsx file=./src/greeting.hooks.6.1.js
589 | ```
590 |
591 |
592 |
593 |
594 |
595 |
596 |
597 | ```jsx file=./src/greeting.hooks.6.2.js
598 | ```
599 |
600 |
601 |
602 |
603 |
604 |
605 |
606 | ```jsx 10,11,17:23,28,31:34 file=./src/greeting.hooks.6.2.js
607 | ```
608 |
609 |
610 |
611 |
612 |
613 |
614 |
615 | ```jsx 10,11,20,23,31:40 file=./src/greeting.hooks.6.3.js
616 | ```
617 |
618 |
619 |
620 |
621 |
622 | ---
623 |
624 |
625 |
626 |
627 |
628 | ```jsx 5:77 file=./src/greeting.class.5.4.js
629 | ```
630 |
631 | ```jsx 9:58 file=./src/greeting.hooks.6.3.js
632 | ```
633 |
634 |
635 |
636 |
637 |
638 | ---
639 |
640 | [Code Surfer Docs](https://codesurfer.pomb.us/)
641 |
--------------------------------------------------------------------------------
/netlify.toml:
--------------------------------------------------------------------------------
1 | [build]
2 | publish = "public/"
3 | command = "npm run build"
4 |
5 | [[redirects]]
6 | from = "/*"
7 | to = "/index.html"
8 | status = 200
--------------------------------------------------------------------------------
/onemorething.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pomber/react-conf-2018-hooks-demo/efe0e4156d98bc1364bc616df6b6c0065dd736c9/onemorething.jpg
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "version": "1.0.0",
4 | "scripts": {
5 | "start": "mdx-deck deck.mdx",
6 | "build": "mdx-deck build deck.mdx",
7 | "test": "echo \"there are no tests\""
8 | },
9 | "devDependencies": {
10 | "code-surfer": "^3.0.0-beta.1",
11 | "mdx-deck": "3.0.10"
12 | },
13 | "name": "react-conf-2018-hooks-demo"
14 | }
15 |
--------------------------------------------------------------------------------
/src/context.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | export const theme = {
4 | golden: "theme-golden",
5 | };
6 |
7 | export const locale = {
8 | rainbow: "🇬🇧",
9 | };
10 |
11 | export const ThemeContext = React.createContext(
12 | theme.golden
13 | );
14 | export const LocaleContext = React.createContext(
15 | locale.rainbow
16 | );
17 |
--------------------------------------------------------------------------------
/src/greeting-loader.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import { useThemeUI } from "theme-ui";
4 |
5 | const load = require.context("./", true, /greeting\..*js$/);
6 |
7 | export default function GreetingLoader({
8 | version = "1.1",
9 | theme,
10 | }) {
11 | const Greeting = load("./greeting." + version + ".js")
12 | .default;
13 |
14 | const { themeUi } = useThemeUI();
15 |
16 | const t = theme || themeUi;
17 |
18 | if (typeof window == `undefined`) {
19 | return null;
20 | }
21 |
22 | return (
23 |
34 |
35 |
36 | );
37 | }
38 |
--------------------------------------------------------------------------------
/src/greeting.1.1.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Row from "./row";
3 |
4 | export default function Greeting(props) {
5 | return (
6 |
9 | );
10 | }
11 |
--------------------------------------------------------------------------------
/src/greeting.class.1.1.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Row from "./row";
3 |
4 | export default class Greeting extends React.Component {
5 | render() {
6 | return (
7 |
8 | {this.props.name}
9 |
10 | );
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/greeting.class.1.2.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Row from "./row";
3 |
4 | export default class Greeting extends React.Component {
5 | constructor(props) {
6 | super(props);
7 | this.state = {
8 | name: "Mary"
9 | };
10 | }
11 |
12 | render() {
13 | return (
14 |
19 | );
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/greeting.class.1.3.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Row from "./row";
3 |
4 | export default class Greeting extends React.Component {
5 | constructor(props) {
6 | super(props);
7 | this.state = {
8 | name: "Mary",
9 | };
10 | this.handleNameChange = this.handleNameChange.bind(
11 | this
12 | );
13 | }
14 |
15 | handleNameChange(e) {
16 | this.setState({ name: e.target.value });
17 | }
18 |
19 | render() {
20 | return (
21 |
29 | );
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/greeting.class.2.1.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Row from "./row";
3 |
4 | export default class Greeting extends React.Component {
5 | constructor(props) {
6 | super(props);
7 | this.state = {
8 | name: "Mary",
9 | surname: "Poppins",
10 | };
11 | this.handleNameChange = this.handleNameChange.bind(
12 | this
13 | );
14 | this.handleSurnameChange = this.handleSurnameChange.bind(
15 | this
16 | );
17 | }
18 |
19 | handleNameChange(e) {
20 | this.setState({ name: e.target.value });
21 | }
22 |
23 | handleSurnameChange(e) {
24 | this.setState({ surname: e.target.value });
25 | }
26 |
27 | render() {
28 | return (
29 |
43 | );
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/greeting.class.3.1.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Row from "./row";
3 | import { ThemeContext, LocaleContext } from "./context";
4 |
5 | export default class Greeting extends React.Component {
6 | constructor(props) {
7 | super(props);
8 | this.state = {
9 | name: "Mary",
10 | surname: "Poppins",
11 | };
12 | this.handleNameChange = this.handleNameChange.bind(
13 | this
14 | );
15 | this.handleSurnameChange = this.handleSurnameChange.bind(
16 | this
17 | );
18 | }
19 |
20 | handleNameChange(e) {
21 | this.setState({ name: e.target.value });
22 | }
23 |
24 | handleSurnameChange(e) {
25 | this.setState({ surname: e.target.value });
26 | }
27 |
28 | render() {
29 | return (
30 |
44 | );
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/greeting.class.3.2.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Row from "./row";
3 | import { ThemeContext, LocaleContext } from "./context";
4 |
5 | export default class Greeting extends React.Component {
6 | constructor(props) {
7 | super(props);
8 | this.state = {
9 | name: "Mary",
10 | surname: "Poppins",
11 | };
12 | this.handleNameChange = this.handleNameChange.bind(
13 | this
14 | );
15 | this.handleSurnameChange = this.handleSurnameChange.bind(
16 | this
17 | );
18 | }
19 |
20 | handleNameChange(e) {
21 | this.setState({ name: e.target.value });
22 | }
23 |
24 | handleSurnameChange(e) {
25 | this.setState({ surname: e.target.value });
26 | }
27 |
28 | render() {
29 | return (
30 |
31 | {theme => (
32 |
46 | )}
47 |
48 | );
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/greeting.class.3.3.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Row from "./row";
3 | import { ThemeContext, LocaleContext } from "./context";
4 |
5 | export default class Greeting extends React.Component {
6 | constructor(props) {
7 | super(props);
8 | this.state = {
9 | name: "Mary",
10 | surname: "Poppins",
11 | };
12 | this.handleNameChange = this.handleNameChange.bind(
13 | this
14 | );
15 | this.handleSurnameChange = this.handleSurnameChange.bind(
16 | this
17 | );
18 | }
19 |
20 | handleNameChange(e) {
21 | this.setState({ name: e.target.value });
22 | }
23 |
24 | handleSurnameChange(e) {
25 | this.setState({ surname: e.target.value });
26 | }
27 |
28 | render() {
29 | return (
30 |
31 | {theme => (
32 |
51 | )}
52 |
53 | );
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/greeting.class.4.1.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Row from "./row";
3 | import { ThemeContext, LocaleContext } from "./context";
4 |
5 | export default class Greeting extends React.Component {
6 | constructor(props) {
7 | super(props);
8 | this.state = {
9 | name: "Mary",
10 | surname: "Poppins",
11 | };
12 | this.handleNameChange = this.handleNameChange.bind(
13 | this
14 | );
15 | this.handleSurnameChange = this.handleSurnameChange.bind(
16 | this
17 | );
18 | }
19 |
20 | componentDidMount() {
21 | document.title =
22 | this.state.name + " " + this.state.surname;
23 | }
24 |
25 | componentDidUpdate() {
26 | document.title =
27 | this.state.name + " " + this.state.surname;
28 | }
29 |
30 | handleNameChange(e) {
31 | this.setState({ name: e.target.value });
32 | }
33 |
34 | handleSurnameChange(e) {
35 | this.setState({ surname: e.target.value });
36 | }
37 |
38 | render() {
39 | return (
40 |
41 | {theme => (
42 |
61 | )}
62 |
63 | );
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/greeting.class.5.1.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Row from "./row";
3 | import { ThemeContext, LocaleContext } from "./context";
4 |
5 | export default class Greeting extends React.Component {
6 | constructor(props) {
7 | super(props);
8 | this.state = {
9 | name: "Mary",
10 | surname: "Poppins",
11 | width: window.innerWidth,
12 | };
13 | this.handleNameChange = this.handleNameChange.bind(
14 | this
15 | );
16 | this.handleSurnameChange = this.handleSurnameChange.bind(
17 | this
18 | );
19 | }
20 |
21 | componentDidMount() {
22 | document.title =
23 | this.state.name + " " + this.state.surname;
24 | }
25 |
26 | componentDidUpdate() {
27 | document.title =
28 | this.state.name + " " + this.state.surname;
29 | }
30 |
31 | handleNameChange(e) {
32 | this.setState({ name: e.target.value });
33 | }
34 |
35 | handleSurnameChange(e) {
36 | this.setState({ surname: e.target.value });
37 | }
38 |
39 | render() {
40 | return (
41 |
42 | {theme => (
43 |
62 | )}
63 |
64 | );
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/greeting.class.5.2.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Row from "./row";
3 | import { ThemeContext, LocaleContext } from "./context";
4 |
5 | export default class Greeting extends React.Component {
6 | constructor(props) {
7 | super(props);
8 | this.state = {
9 | name: "Mary",
10 | surname: "Poppins",
11 | width: window.innerWidth,
12 | };
13 | this.handleNameChange = this.handleNameChange.bind(
14 | this
15 | );
16 | this.handleSurnameChange = this.handleSurnameChange.bind(
17 | this
18 | );
19 | }
20 |
21 | componentDidMount() {
22 | document.title =
23 | this.state.name + " " + this.state.surname;
24 | }
25 |
26 | componentDidUpdate() {
27 | document.title =
28 | this.state.name + " " + this.state.surname;
29 | }
30 |
31 | handleNameChange(e) {
32 | this.setState({ name: e.target.value });
33 | }
34 |
35 | handleSurnameChange(e) {
36 | this.setState({ surname: e.target.value });
37 | }
38 |
39 | render() {
40 | return (
41 |
42 | {theme => (
43 |
63 | )}
64 |
65 | );
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/greeting.class.5.3.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Row from "./row";
3 | import { ThemeContext, LocaleContext } from "./context";
4 |
5 | export default class Greeting extends React.Component {
6 | constructor(props) {
7 | super(props);
8 | this.state = {
9 | name: "Mary",
10 | surname: "Poppins",
11 | width: window.innerWidth,
12 | };
13 | this.handleNameChange = this.handleNameChange.bind(
14 | this
15 | );
16 | this.handleSurnameChange = this.handleSurnameChange.bind(
17 | this
18 | );
19 | this.handleResize = this.handleResize.bind(this);
20 | }
21 |
22 | componentDidMount() {
23 | document.title =
24 | this.state.name + " " + this.state.surname;
25 | window.addEventListener("resize", this.handleResize);
26 | }
27 |
28 | componentDidUpdate() {
29 | document.title =
30 | this.state.name + " " + this.state.surname;
31 | }
32 |
33 | handleNameChange(e) {
34 | this.setState({ name: e.target.value });
35 | }
36 |
37 | handleSurnameChange(e) {
38 | this.setState({ surname: e.target.value });
39 | }
40 |
41 | handleResize() {
42 | this.setState({ width: window.innerWidth });
43 | }
44 |
45 | render() {
46 | return (
47 |
48 | {theme => (
49 |
69 | )}
70 |
71 | );
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/greeting.class.5.4.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Row from "./row";
3 | import { ThemeContext, LocaleContext } from "./context";
4 |
5 | export default class Greeting extends React.Component {
6 | constructor(props) {
7 | super(props);
8 | this.state = {
9 | name: "Mary",
10 | surname: "Poppins",
11 | width: window.innerWidth,
12 | };
13 | this.handleNameChange = this.handleNameChange.bind(
14 | this
15 | );
16 | this.handleSurnameChange = this.handleSurnameChange.bind(
17 | this
18 | );
19 | this.handleResize = this.handleResize.bind(this);
20 | }
21 |
22 | componentDidMount() {
23 | document.title =
24 | this.state.name + " " + this.state.surname;
25 | window.addEventListener("resize", this.handleResize);
26 | }
27 |
28 | componentDidUpdate() {
29 | document.title =
30 | this.state.name + " " + this.state.surname;
31 | }
32 |
33 | componentWillUnmount() {
34 | window.removeEventListener("resize", this.handleResize);
35 | }
36 |
37 | handleNameChange(e) {
38 | this.setState({ name: e.target.value });
39 | }
40 |
41 | handleSurnameChange(e) {
42 | this.setState({ surname: e.target.value });
43 | }
44 |
45 | handleResize() {
46 | this.setState({ width: window.innerWidth });
47 | }
48 |
49 | render() {
50 | return (
51 |
52 | {theme => (
53 |
73 | )}
74 |
75 | );
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/src/greeting.hooks.1.1.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Row from "./row";
3 |
4 | export default function Greeting(props) {
5 | const name = ???
6 |
7 | return (
8 |
13 | );
14 | }
15 |
--------------------------------------------------------------------------------
/src/greeting.hooks.1.2.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Row from "./row";
3 |
4 | export default function Greeting(props) {
5 | const name = ???
6 | const setName = ???
7 |
8 | function handleNameChange(e) {
9 | setName(e.target.value);
10 | }
11 |
12 | return (
13 |
18 | );
19 | }
20 |
--------------------------------------------------------------------------------
/src/greeting.hooks.1.3.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Row from "./row";
3 |
4 | export default function Greeting(props) {
5 | const [name, setName] = ???
6 |
7 | function handleNameChange(e) {
8 | setName(e.target.value);
9 | }
10 |
11 | return (
12 |
17 | );
18 | }
19 |
--------------------------------------------------------------------------------
/src/greeting.hooks.1.4.js:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import Row from "./row";
3 |
4 | export default function Greeting(props) {
5 | const [name, setName] = useState("Mary");
6 |
7 | function handleNameChange(e) {
8 | setName(e.target.value);
9 | }
10 |
11 | return (
12 |
17 | );
18 | }
19 |
--------------------------------------------------------------------------------
/src/greeting.hooks.2.1.js:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import Row from "./row";
3 |
4 | export default function Greeting(props) {
5 | const [name, setName] = useState("Mary");
6 | const [surname, setSurname] = useState("Poppins");
7 |
8 | function handleNameChange(e) {
9 | setName(e.target.value);
10 | }
11 |
12 | function handleSurnameChange(e) {
13 | setSurname(e.target.value);
14 | }
15 |
16 | return (
17 |
28 | );
29 | }
30 |
--------------------------------------------------------------------------------
/src/greeting.hooks.3.1.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useContext } from "react";
2 | import Row from "./row";
3 | import { ThemeContext, LocaleContext } from "./context";
4 |
5 | export default function Greeting(props) {
6 | const [name, setName] = useState("Mary");
7 | const [surname, setSurname] = useState("Poppins");
8 |
9 | function handleNameChange(e) {
10 | setName(e.target.value);
11 | }
12 |
13 | function handleSurnameChange(e) {
14 | setSurname(e.target.value);
15 | }
16 |
17 | return (
18 |
29 | );
30 | }
31 |
--------------------------------------------------------------------------------
/src/greeting.hooks.3.2.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useContext } from "react";
2 | import Row from "./row";
3 | import { ThemeContext, LocaleContext } from "./context";
4 |
5 | export default function Greeting(props) {
6 | const [name, setName] = useState("Mary");
7 | const [surname, setSurname] = useState("Poppins");
8 | const theme = useContext(ThemeContext);
9 |
10 | function handleNameChange(e) {
11 | setName(e.target.value);
12 | }
13 |
14 | function handleSurnameChange(e) {
15 | setSurname(e.target.value);
16 | }
17 |
18 | return (
19 |
30 | );
31 | }
32 |
--------------------------------------------------------------------------------
/src/greeting.hooks.3.3.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useContext } from "react";
2 | import Row from "./row";
3 | import { ThemeContext, LocaleContext } from "./context";
4 |
5 | export default function Greeting(props) {
6 | const [name, setName] = useState("Mary");
7 | const [surname, setSurname] = useState("Poppins");
8 | const theme = useContext(ThemeContext);
9 | const locale = useContext(LocaleContext);
10 |
11 | function handleNameChange(e) {
12 | setName(e.target.value);
13 | }
14 |
15 | function handleSurnameChange(e) {
16 | setSurname(e.target.value);
17 | }
18 |
19 | return (
20 |
32 | );
33 | }
34 |
--------------------------------------------------------------------------------
/src/greeting.hooks.4.1.js:
--------------------------------------------------------------------------------
1 | import React, {
2 | useState,
3 | useContext,
4 | useEffect,
5 | } from "react";
6 | import Row from "./row";
7 | import { ThemeContext, LocaleContext } from "./context";
8 |
9 | export default function Greeting(props) {
10 | const [name, setName] = useState("Mary");
11 | const [surname, setSurname] = useState("Poppins");
12 | const theme = useContext(ThemeContext);
13 | const locale = useContext(LocaleContext);
14 |
15 | function handleNameChange(e) {
16 | setName(e.target.value);
17 | }
18 |
19 | function handleSurnameChange(e) {
20 | setSurname(e.target.value);
21 | }
22 |
23 | return (
24 |
36 | );
37 | }
38 |
--------------------------------------------------------------------------------
/src/greeting.hooks.4.2.js:
--------------------------------------------------------------------------------
1 | import React, {
2 | useState,
3 | useContext,
4 | useEffect,
5 | } from "react";
6 | import Row from "./row";
7 | import { ThemeContext, LocaleContext } from "./context";
8 |
9 | export default function Greeting(props) {
10 | const [name, setName] = useState("Mary");
11 | const [surname, setSurname] = useState("Poppins");
12 | const theme = useContext(ThemeContext);
13 | const locale = useContext(LocaleContext);
14 |
15 | useEffect(() => {
16 | document.title = name + " " + surname;
17 | });
18 |
19 | function handleNameChange(e) {
20 | setName(e.target.value);
21 | }
22 |
23 | function handleSurnameChange(e) {
24 | setSurname(e.target.value);
25 | }
26 |
27 | return (
28 |
40 | );
41 | }
42 |
--------------------------------------------------------------------------------
/src/greeting.hooks.5.1.js:
--------------------------------------------------------------------------------
1 | import React, {
2 | useState,
3 | useContext,
4 | useEffect,
5 | } from "react";
6 | import Row from "./row";
7 | import { ThemeContext, LocaleContext } from "./context";
8 |
9 | export default function Greeting(props) {
10 | const [name, setName] = useState("Mary");
11 | const [surname, setSurname] = useState("Poppins");
12 | const theme = useContext(ThemeContext);
13 | const locale = useContext(LocaleContext);
14 |
15 | useEffect(() => {
16 | document.title = name + " " + surname;
17 | });
18 |
19 | const [width, setWidth] = useState(window.innerWidth);
20 |
21 | function handleNameChange(e) {
22 | setName(e.target.value);
23 | }
24 |
25 | function handleSurnameChange(e) {
26 | setSurname(e.target.value);
27 | }
28 |
29 | return (
30 |
43 | );
44 | }
45 |
--------------------------------------------------------------------------------
/src/greeting.hooks.5.2.js:
--------------------------------------------------------------------------------
1 | import React, {
2 | useState,
3 | useContext,
4 | useEffect,
5 | } from "react";
6 | import Row from "./row";
7 | import { ThemeContext, LocaleContext } from "./context";
8 |
9 | export default function Greeting(props) {
10 | const [name, setName] = useState("Mary");
11 | const [surname, setSurname] = useState("Poppins");
12 | const theme = useContext(ThemeContext);
13 | const locale = useContext(LocaleContext);
14 |
15 | useEffect(() => {
16 | document.title = name + " " + surname;
17 | });
18 |
19 | const [width, setWidth] = useState(window.innerWidth);
20 | useEffect(() => {
21 | const handleResize = () => setWidth(window.innerWidth);
22 | window.addEventListener("resize", handleResize);
23 | });
24 |
25 | function handleNameChange(e) {
26 | setName(e.target.value);
27 | }
28 |
29 | function handleSurnameChange(e) {
30 | setSurname(e.target.value);
31 | }
32 |
33 | return (
34 |
47 | );
48 | }
49 |
--------------------------------------------------------------------------------
/src/greeting.hooks.5.3.js:
--------------------------------------------------------------------------------
1 | import React, {
2 | useState,
3 | useContext,
4 | useEffect,
5 | } from "react";
6 | import Row from "./row";
7 | import { ThemeContext, LocaleContext } from "./context";
8 |
9 | export default function Greeting(props) {
10 | const [name, setName] = useState("Mary");
11 | const [surname, setSurname] = useState("Poppins");
12 | const theme = useContext(ThemeContext);
13 | const locale = useContext(LocaleContext);
14 |
15 | useEffect(() => {
16 | document.title = name + " " + surname;
17 | });
18 |
19 | const [width, setWidth] = useState(window.innerWidth);
20 | useEffect(() => {
21 | const handleResize = () => setWidth(window.innerWidth);
22 | window.addEventListener("resize", handleResize);
23 | return () => {
24 | window.removeEventListener("resize", handleResize);
25 | };
26 | });
27 |
28 | function handleNameChange(e) {
29 | setName(e.target.value);
30 | }
31 |
32 | function handleSurnameChange(e) {
33 | setSurname(e.target.value);
34 | }
35 |
36 | return (
37 |
50 | );
51 | }
52 |
--------------------------------------------------------------------------------
/src/greeting.hooks.6.1.js:
--------------------------------------------------------------------------------
1 | import React, {
2 | useState,
3 | useContext,
4 | useEffect,
5 | } from "react";
6 | import Row from "./row";
7 | import { ThemeContext, LocaleContext } from "./context";
8 |
9 | export default function Greeting(props) {
10 | const [name, setName] = useState("Mary");
11 | const [surname, setSurname] = useState("Poppins");
12 | const theme = useContext(ThemeContext);
13 | const locale = useContext(LocaleContext);
14 | const width = useWindowWidth();
15 |
16 | useEffect(() => {
17 | document.title = name + " " + surname;
18 | });
19 |
20 | function handleNameChange(e) {
21 | setName(e.target.value);
22 | }
23 |
24 | function handleSurnameChange(e) {
25 | setSurname(e.target.value);
26 | }
27 |
28 | return (
29 |
42 | );
43 | }
44 |
45 | function useWindowWidth() {
46 | const [width, setWidth] = useState(window.innerWidth);
47 | useEffect(() => {
48 | const handleResize = () => setWidth(window.innerWidth);
49 | window.addEventListener("resize", handleResize);
50 | return () => {
51 | window.removeEventListener("resize", handleResize);
52 | };
53 | });
54 | return width;
55 | }
56 |
--------------------------------------------------------------------------------
/src/greeting.hooks.6.2.js:
--------------------------------------------------------------------------------
1 | import React, {
2 | useState,
3 | useContext,
4 | useEffect,
5 | } from "react";
6 | import Row from "./row";
7 | import { ThemeContext, LocaleContext } from "./context";
8 |
9 | export default function Greeting(props) {
10 | const [name, setName] = useState("Mary");
11 | const [surname, setSurname] = useState("Poppins");
12 | const theme = useContext(ThemeContext);
13 | const locale = useContext(LocaleContext);
14 | const width = useWindowWidth();
15 | useDocumentTitle(name + " " + surname);
16 |
17 | function handleNameChange(e) {
18 | setName(e.target.value);
19 | }
20 |
21 | function handleSurnameChange(e) {
22 | setSurname(e.target.value);
23 | }
24 |
25 | return (
26 |
39 | );
40 | }
41 |
42 | function useDocumentTitle(title) {
43 | useEffect(() => {
44 | document.title = title;
45 | });
46 | }
47 |
48 | function useWindowWidth() {
49 | const [width, setWidth] = useState(window.innerWidth);
50 | useEffect(() => {
51 | const handleResize = () => setWidth(window.innerWidth);
52 | window.addEventListener("resize", handleResize);
53 | return () => {
54 | window.removeEventListener("resize", handleResize);
55 | };
56 | });
57 | return width;
58 | }
59 |
--------------------------------------------------------------------------------
/src/greeting.hooks.6.3.js:
--------------------------------------------------------------------------------
1 | import React, {
2 | useState,
3 | useContext,
4 | useEffect,
5 | } from "react";
6 | import Row from "./row";
7 | import { ThemeContext, LocaleContext } from "./context";
8 |
9 | export default function Greeting(props) {
10 | const name = useFormInput("Mary");
11 | const surname = useFormInput("Poppins");
12 | const theme = useContext(ThemeContext);
13 | const locale = useContext(LocaleContext);
14 | const width = useWindowWidth();
15 | useDocumentTitle(name.value + " " + surname.value);
16 |
17 | return (
18 |
28 | );
29 | }
30 |
31 | function useFormInput(initialValue) {
32 | const [value, setValue] = useState(initialValue);
33 | function handleChange(e) {
34 | setValue(e.target.value);
35 | }
36 | return {
37 | value,
38 | onChange: handleChange,
39 | };
40 | }
41 |
42 | function useDocumentTitle(title) {
43 | useEffect(() => {
44 | document.title = title;
45 | });
46 | }
47 |
48 | function useWindowWidth() {
49 | const [width, setWidth] = useState(window.innerWidth);
50 | useEffect(() => {
51 | const handleResize = () => setWidth(window.innerWidth);
52 | window.addEventListener("resize", handleResize);
53 | return () => {
54 | window.removeEventListener("resize", handleResize);
55 | };
56 | });
57 | return width;
58 | }
59 |
--------------------------------------------------------------------------------
/src/row.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import "./styles.css";
3 |
4 | const Row = props => (
5 |
6 | {props.label}
7 | {props.children}
8 |
9 | );
10 |
11 | export default Row;
12 |
--------------------------------------------------------------------------------
/src/styles.css:
--------------------------------------------------------------------------------
1 | /* From https://github.com/donycisneros/react-hooks-demo */
2 |
3 | @import url("https://fonts.googleapis.com/css?family=Playfair+Display:400,900i");
4 |
5 | section {
6 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI",
7 | "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans",
8 | "Droid Sans", "Helvetica Neue", sans-serif;
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 | width: 360px;
12 | padding: 30px;
13 | background-color: #d1dae0;
14 | border-bottom: 4px solid #abb5b8;
15 | box-shadow: 8px 8px 0px 0px #000000;
16 | text-align: initial;
17 | font-size: 1.5rem;
18 | max-width: 90%;
19 | }
20 | .row:not(:first-child) {
21 | margin-top: 25px;
22 | }
23 | .row-title,
24 | section input {
25 | font-weight: bold;
26 | color: #696969;
27 | padding-left: 8px;
28 | }
29 | section input {
30 | border: none;
31 | font-size: 2.5rem;
32 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI",
33 | "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans",
34 | "Droid Sans", "Helvetica Neue", sans-serif;
35 | }
36 | .row-content {
37 | font-size: 2.5rem;
38 | font-weight: bold;
39 | color: #000000;
40 | display: block;
41 | width: 100%;
42 | margin-top: 15px;
43 | }
44 | .row-content input,
45 | .row-content input:focus {
46 | padding: 7px;
47 | color: #000000;
48 | border-radius: 8px;
49 | width: 100%;
50 | outline: none;
51 | }
52 | .row-content input {
53 | background-color: transparent;
54 | }
55 | .row-content input:focus {
56 | background-color: #a0aaad;
57 | }
58 | .row-content input:focus::selection {
59 | background: #fff3a3;
60 | }
61 | .row-content input:focus::-moz-selection {
62 | background: #fff3a3;
63 | }
64 |
65 | /*========== Theme Golden ==========*/
66 |
67 | .theme-golden {
68 | font-family: "Playfair Display", serif;
69 | background: #ffc42b;
70 | border-top: 2px solid #ffd979;
71 | border-bottom-color: #b48700;
72 | }
73 | .theme-golden .row,
74 | .theme-golden .row-content input {
75 | font-family: "Playfair Display", serif;
76 | text-align: center;
77 | }
78 | .theme-golden .row-content input {
79 | font-style: italic;
80 | }
81 | .theme-golden .row-content input:focus {
82 | background-color: #b68b1b;
83 | }
84 | .theme-golden .row-content input:focus::selection {
85 | background: #ffea98;
86 | }
87 | .theme-golden .row-content input:focus::-moz-selection {
88 | background: #ffea98;
89 | }
90 | .theme-golden .row {
91 | position: relative;
92 | z-index: 1;
93 | }
94 | .theme-golden .row:before {
95 | border-top: 1px solid #d4990d;
96 | content: "";
97 | margin: 0 auto;
98 | position: absolute;
99 | top: 15%;
100 | left: 0;
101 | right: 0;
102 | bottom: 0;
103 | width: 95%;
104 | z-index: -1;
105 | }
106 | .theme-golden .row-title {
107 | color: #936508;
108 | background: #ffc42b;
109 | padding: 0 7px;
110 | }
111 |
112 | /*========== Media Queries ==========*/
113 |
114 | @media (max-width: 415px) {
115 | .theme-golden {
116 | max-width: 90vw;
117 | margin: 0 auto;
118 | }
119 | section input {
120 | font-size: 1.2rem;
121 | }
122 | }
123 |
124 | @media (max-width: 900px) {
125 | section {
126 | font-size: 1rem;
127 | padding: 15px;
128 | }
129 | .row-content,
130 | section input {
131 | font-size: 1.2rem;
132 | }
133 | .row-content {
134 | margin-top: 1px;
135 | }
136 | .row:not(:first-child) {
137 | margin-top: 2px;
138 | }
139 | section input {
140 | padding: 0 7px 2px;
141 | }
142 | }
143 |
--------------------------------------------------------------------------------