├── package.json ├── public └── index.html └── src ├── Callback.js ├── Context.js ├── DebugValue.js ├── Effect.js ├── ImperativeHandle.js ├── LayoutEffect.js ├── Memo.js ├── Reducer.js ├── Ref.js ├── State.js ├── index.js └── styles.css /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-hooks-examples-v3", 3 | "version": "1.0.0", 4 | "description": "", 5 | "keywords": [], 6 | "main": "src/index.js", 7 | "dependencies": { 8 | "react": "17.0.1", 9 | "react-dom": "17.0.1", 10 | "react-scripts": "4.0.3" 11 | }, 12 | "devDependencies": {}, 13 | "scripts": { 14 | "start": "react-scripts start", 15 | "build": "react-scripts build", 16 | "test": "react-scripts test --env=jsdom", 17 | "eject": "react-scripts eject" 18 | }, 19 | "browserslist": [">0.2%", "not dead", "not ie <= 11", "not op_mini all"] 20 | } 21 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 14 | 23 | React App 24 | 25 | 26 | 27 | 30 |
31 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/Callback.js: -------------------------------------------------------------------------------- 1 | import { useState, useEffect, useCallback, memo } from "react"; 2 | 3 | const ExpensiveComputationComponent = memo(({ compute, count }) => { 4 | return ( 5 |
6 |

computed: {compute(count)}

7 |

last re-render {new Date().toLocaleTimeString()}

8 |
9 | ); 10 | }); 11 | 12 | const CallbackComponent = () => { 13 | const [time, setTime] = useState(new Date()); 14 | const [count, setCount] = useState(1); 15 | useEffect(() => { 16 | const timer = setTimeout(() => setTime(new Date()), 1000); 17 | return () => clearTimeout(timer); 18 | }); 19 | 20 | const fibonacci = (n) => { 21 | if (n <= 1) { 22 | return 1; 23 | } 24 | 25 | return fibonacci(n - 1) + fibonacci(n - 2); 26 | }; 27 | 28 | return ( 29 |
30 |

useCallback Example {time.toLocaleTimeString()}

31 | 34 | 38 |
39 | ); 40 | }; 41 | 42 | export default CallbackComponent; 43 | -------------------------------------------------------------------------------- /src/Context.js: -------------------------------------------------------------------------------- 1 | import { useState, useContext, createContext } from "react"; 2 | 3 | const UserContext = createContext([ 4 | { 5 | firstName: "Bob", 6 | lastName: "Bobberson", 7 | suffix: 1, 8 | email: "bobbobberson@example.com" 9 | }, 10 | (obj) => obj 11 | ]); 12 | 13 | const LevelFive = () => { 14 | const [user, setUser] = useContext(UserContext); 15 | 16 | return ( 17 |
18 |
{`${user.firstName} ${user.lastName} the ${user.suffix} born`}
19 | 26 |
27 | ); 28 | }; 29 | 30 | const LevelFour = () => ( 31 |
32 |

fourth level

33 | 34 |
35 | ); 36 | 37 | const LevelThree = () => ( 38 |
39 |

third level

40 | 41 |
42 | ); 43 | 44 | const LevelTwo = () => ( 45 |
46 |

second level

47 | 48 |
49 | ); 50 | 51 | const ContextComponent = () => { 52 | const userState = useState({ 53 | firstName: "James", 54 | lastName: "Jameson", 55 | suffix: 1, 56 | email: "jamesjameson@example.com" 57 | }); 58 | 59 | return ( 60 | 61 |

first level

62 | 63 |
64 | ); 65 | }; 66 | 67 | export default ContextComponent; 68 | -------------------------------------------------------------------------------- /src/DebugValue.js: -------------------------------------------------------------------------------- 1 | import { useState, useEffect, useDebugValue } from "react"; 2 | 3 | const useIsRaining = () => { 4 | const [isRaining, setIsRaining] = useState(false); 5 | 6 | useEffect(() => { 7 | // pretend here you'd make an API request to a weather API 8 | // instead we're just going to fake it 9 | 10 | setIsRaining(Math.random() > 0.5); 11 | }); 12 | 13 | useDebugValue(isRaining ? "Is Raining" : "Is Not Raining"); 14 | 15 | return isRaining; 16 | }; 17 | 18 | const DebugValueComponent = () => { 19 | const isRaining = useIsRaining(); 20 | 21 | return ( 22 |
23 |

useDebugValue Example

24 |

Do you need a coat today? {isRaining ? "yes" : "maybe"}

25 |
26 | ); 27 | }; 28 | 29 | export default DebugValueComponent; 30 | -------------------------------------------------------------------------------- /src/Effect.js: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from "react"; 2 | 3 | const EffectComponent = () => { 4 | const [time, setTime] = useState(new Date()); 5 | 6 | useEffect(() => { 7 | const timer = setTimeout(() => setTime(new Date()), 1000); 8 | return () => clearTimeout(timer); 9 | }); 10 | 11 | return

useEffect Example: {time.toLocaleTimeString()}

; 12 | }; 13 | 14 | export default EffectComponent; 15 | -------------------------------------------------------------------------------- /src/ImperativeHandle.js: -------------------------------------------------------------------------------- 1 | import { useState, useRef, useImperativeHandle, forwardRef } from "react"; 2 | 3 | const ElaborateInput = forwardRef( 4 | ({ hasError, placeholder, value, update }, ref) => { 5 | const inputRef = useRef(); 6 | useImperativeHandle(ref, () => { 7 | return { 8 | focus() { 9 | inputRef.current.focus(); 10 | } 11 | }; 12 | }); 13 | return ( 14 | update(e.target.value)} 18 | placeholder={placeholder} 19 | style={{ 20 | padding: "5px 15px", 21 | borderWidth: "3px", 22 | borderStyle: "solid", 23 | borderColor: hasError ? "crimson" : "#999", 24 | borderRadius: "5px", 25 | margin: "0 10px", 26 | textAlign: "center" 27 | }} 28 | /> 29 | ); 30 | } 31 | ); 32 | 33 | const ImperativeHandleComponent = () => { 34 | const [city, setCity] = useState("Seattle"); 35 | const [state, setState] = useState("WA"); 36 | const [error, setError] = useState(""); 37 | const cityEl = useRef(); 38 | const stateEl = useRef(); 39 | 40 | function validate() { 41 | // lol I found it on StackOverflow : https://stackoverflow.com/a/25677072 42 | if ( 43 | !/^([a-zA-Z\u0080-\u024F]+(?:. |-| |'))*[a-zA-Z\u0080-\u024F]+$/.test( 44 | city 45 | ) 46 | ) { 47 | setError("city"); 48 | cityEl.current.focus(); 49 | return; 50 | } 51 | 52 | if (!/^[A-Z]{2}$/.test(state)) { 53 | setError("state"); 54 | stateEl.current.focus(); 55 | return; 56 | } 57 | 58 | setError(""); 59 | alert("valid form!"); 60 | } 61 | 62 | return ( 63 |
64 |

useImperativeHandle Example

65 | 72 | 79 | 80 |
81 | ); 82 | }; 83 | 84 | export default ImperativeHandleComponent; 85 | -------------------------------------------------------------------------------- /src/LayoutEffect.js: -------------------------------------------------------------------------------- 1 | import { useState, useLayoutEffect, useRef } from "react"; 2 | 3 | const LayoutEffectComponent = () => { 4 | const [width, setWidth] = useState(0); 5 | const [height, setHeight] = useState(0); 6 | const el = useRef(); 7 | 8 | useLayoutEffect(() => { 9 | setWidth(el.current.clientWidth); 10 | setHeight(el.current.clientHeight); 11 | }); 12 | 13 | return ( 14 |
15 |

useLayoutEffect Example

16 |

textarea width: {width}px

17 |

textarea height: {height}px

18 |