` is necessary because JSX does not allow us to return multiple elements. Write something like the following is wrong.
4 | ```js
5 | return (
6 |
8 | )
9 | ```
10 | If we want to return multiple elements in JSX, before of `React.Fragment`, we had to do like:
11 | ```js
12 | return (
13 |
` that maybe we do not want to show in the resulting HTML. Since the advent of `React.Fragment` we can write something like:
20 | ```js
21 | return (
22 |
23 | Hello World
24 | Goodbye World
25 |
26 | )
27 | ```
28 | This will not create a new element in our HTML but will let us add additional elements into our JSX.
29 |
30 | Since `React.Fragment` is so commonly used, beside the ability to deconstruct it from the React main library itself, we have a shorthand way to use it:
31 | ```js
32 | return (
33 | <>
34 |
Hello World
35 |
Goodbye World
36 | >
37 | )
38 | ```
--------------------------------------------------------------------------------
/React/React.createElement().md:
--------------------------------------------------------------------------------
1 | The `createElement()` method takes two params:
2 | * `element` - a string representing the HTML element that we want to create
3 | * `props` - a JS object that will keep all the information needed to render the element (id, class, text...)
4 |
5 | A basic creation of a React element is:
6 | ```js
7 | React.createElement( 'div', {
8 | className: 'container',
9 | children: 'Hello World'
10 | })
11 | ```
12 |
13 | The `children` are the content of the element, it could be a string or any other elements.
14 |
15 | Beside that the `children` is a special `prop` in React and you can pass it any number of children after the prop declaration, basically this snippet:
16 | ```js
17 | React.createElement( 'div', {
18 | className: 'container',
19 | children: ['Hello', ' ', 'World']
20 | })
21 | ```
22 | Is equal to:
23 | ```js
24 | React.createElement(
25 | 'div',
26 | { className: 'container'},
27 | 'Hello', ' ', 'World'
28 | )
29 | ```
30 | In both cases I am passing multiple elements within an array but in the first one it is explicit in the second one is React doing it's magic. If you `console.log()` the element you'll find out that both have the same structure.
31 |
32 | If I need to pass down more DOM elements I need to create them first:
33 | ```js
34 | // If I do not need props they could be null or empty obj
35 | const spanHelloElement = React.createElement( 'span', null, 'Hello')
36 | const spanWorldElement = React.createElement( 'span', {}, 'World')
37 | const reactElement = React.createElement(
38 | 'div',
39 | { className: "container" },
40 | spanHelloElement, ' ', spanWorldElement
41 | );
42 |
43 | ReactDOM.render( reactElement, rootElement )
--------------------------------------------------------------------------------
/React/React.useEffect().md:
--------------------------------------------------------------------------------
1 | `React.useEffect()` is the Hook way that let us run some code when some state/values/props have changed. At first, when Hooks have been introduced, this looked like the answer to the [[lifecycle methods]] that we were used to use in a React class component.
2 |
3 | > This is very similar to [[React.useLayoutEffect()|useLayoutEffect]] with the main difference that when we use the `useEffect` Hook it gets run **after** the component renders and ensures that your effect callback does not block browser painting.
4 |
5 | Anyway as we will dig deeper in this note `React.useEffect()` has many benefits that go over the standard lifecycle methods.
6 | Basic syntax:
7 | ```js
8 | React.useEffect( () => {
9 | // The code in here will run at each render
10 | })
11 | ```
12 |
13 | The `useEffect` Hook has a *dependency list*, an array that will contain the values that it needs to monitor in order to know if it has to fire or not.
14 | ```js
15 | React.useEffect( () => {
16 | // The code in here will run at first render
17 | }, [dependency, list])
18 | ```
19 | Most of the time the items that we add to the dependency list are just variables holding values **but**, as happen for the [[2. useCallback custom hooks|useCallback exercise]] sometimes *'looks like'* we need to pass in a fn.
20 | ```js
21 | // Custom Hook to define async operations
22 | function useAsync( asyncCallback, initialState ){
23 | const [state, dispatch] = // state definition
24 |
25 | React.useEffect(() => {
26 | const promise = asyncCallback(); // <- this is a dependency
27 | // Other code not important
28 | },
29 | [asyncCallback]); // <- WRONG!!!
30 |
31 | }
32 | ```
33 | Maybe you're asking *"why should it be bad?"*
34 |
35 | I do not mean that is *always* a bad thing, the fact is that we will need to execute our `useEffect` at each render because the `asyncCallback` we're passing, in this case, will be a *'new fn at each render'*.
36 | ```js
37 | // How we use the custom Hook
38 | function PokemonInfo({pokemonName}) {
39 | const state = useAsync(
40 | () => {
41 | // the body of the asyncCallback
42 | },
43 | // more code...
44 | )
45 |
46 | ```
47 | As you can see the `asyncCallback` is defined **inside the component** and from the React point of view it'll be a new function at each render and this is not a good solution since will let us wasting resources.
48 |
49 | In order to solve this issue we have to identify **what really changes** and pass it as a parameter to insert it in the dependencies list.
50 |
51 | In this specific case the thing that was changing was the `pokemonName` so we changed the [[custom Hook]] declaration and it's use:
52 | ```js
53 | // Custom Hook to define async operations
54 | function useAsync(asyncCallback, initialState, dependencies) {
55 | const [state, dispatch] = // state definition
56 |
57 | React.useEffect(() => {
58 | // more code...
59 | },
60 | dependencies); // <- I am using the passed dependencies
61 |
62 | return state
63 | }
64 |
65 | function PokemonInfo({pokemonName}) {
66 | const state = useAsync(
67 | () => {
68 | // the body of the asyncCallback
69 | },
70 | // more code...
71 | [pokemonName], // <- this is the dependendies we pass to our custom Hook
72 | )
73 | ```
74 | Probably you're using ESLint in your project, and btw congrats in doing so, and you saw the warning about dependencies of `useEffect`. To solve this you can just add a comment that will stop ESLint for the next line or use [[React.useCallback()|useCallback]] to create a [[memoize|memoized]] version of the `asyncCallback` fn.
75 | ```js
76 | // eslint-disable-next-line react-hooks/exhaustive-deps
77 | ```
78 | ## Best benefits of `useEffect`
79 | ## Common behavior of `useEffect`
80 | ### Running at each render - without dependencies array
81 | ```js
82 | React.useEffect( () => {
83 | // The code in here will run at each render
84 | })
85 | ```
86 | ### Running after mount the component - with an empty dependencies array
87 | ```js
88 | React.useEffect( () => {
89 | // The code in here will run at first render
90 | }, [])
91 | ```
92 | ### Run when a specific prop or state changes - with a dependencies array
93 | ```js
94 | React.useEffect( () => {
95 | // The code in here will run each time 'specific' changes
96 | }, [specific])
97 | ```
98 |
99 | ## Use examples
100 | ### Set a ref to a mounted DOM node
101 | ### Make an HTTP request
102 | ### Write on localStorage
103 | Here we are creating the [[custom Hook]] `useLocalStorageState` that is helping us save our state into the [[localStorage]] of our browser. You can see the `useEffect` Hook in action.
104 | ```js
105 | function useLocalStorageState(key, defaultValue = '') {
106 | const [state, setState] = React.useState(
107 | () => window.localStorage.getItem(key) ||
108 | defaultValue,
109 | )
110 | React.useEffect( () => {
111 | window.localStorage.setItem(key, state)
112 | }, [key, state] )
113 |
114 | return [ state, setState ]
115 | }
116 | ```
117 | The dependency array hold the values for `key` and `state`, as you know, each time those values are different the `useEffect` will run.
118 |
119 | In this example we are using the `useEffect` Hook only to save the value held in `state` inside the [[localStorage]].
--------------------------------------------------------------------------------
/React/React.useReducer().md:
--------------------------------------------------------------------------------
1 | Hook that let us handle the state of our application in a Redux-like way, basically we store the state and we edit via some actions that we dispatch in it.
2 |
3 | Will be back with an improved explanation but if you know Redux you're pretty close 😉
--------------------------------------------------------------------------------
/React/React.useRef()].md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndreaBarghigiani/EpicReactNotes/32f54006c876cf66cc1e856626cc109813d97a1b/React/React.useRef()].md
--------------------------------------------------------------------------------
/React/React.useState().md:
--------------------------------------------------------------------------------
1 | Accept a value that will be used to set the initial state of our custom component, this functions returns two values in an array:
2 | 1. the first value will be the value of the state at the current time we're calling it
3 | 2. the second value is a function that will let us update the state
4 |
5 | React returns those two values in a form of an array and generally we [[destruct]] those to make simplier to access and use them later.
6 | ```js
7 | // Here I define a new state called state, to update it I'll use setState()
8 | // and it's initial value will be 0
9 | const [ state, setState ] = React.useState(0);
10 | ```
11 | State can be defined as: data that changes over time.
12 |
13 | Each time the state of a component gets changed React will render the component to update the UI with the new information.
14 |
15 | ## Performance tip
16 | The `useState` Hook will get called each time a component render (and re-renders) and if we use some complex functions or if we have to rely on API to calculate the initial value of our state this could be a problem because the function that we use **get's called each time**.
17 |
18 | To avoid this instead of passing the function call that calculates the initial value for the state we can pass it within a function to let React call it only the first time a component gets rendered.
19 |
20 | ```js
21 | function someComplexCalcs(){
22 | // Your complex calcs to generate the initial value
23 | }
24 |
25 | // We call someComplexCalcs() each time component renders or re-renders
26 | const [state, setState] = React.useState(someComplexCalcs())
27 |
28 | // We execute someComplexCalcs() only once at first render
29 | const [state, setState] = React.useState( () => someComplexCalcs())
30 | ```
31 | This approach is called *lazy initialization* and will save us from bottlenecks in our app on sequential renders.
--------------------------------------------------------------------------------
/React/ReactDOM.render().md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndreaBarghigiani/EpicReactNotes/32f54006c876cf66cc1e856626cc109813d97a1b/React/ReactDOM.render().md
--------------------------------------------------------------------------------
/React/custom Hook.md:
--------------------------------------------------------------------------------
1 | A custom Hook is a normal JavaScript function that wrap shared logic between components. What makes a custom Hook a custom Hook is:
2 | * the fn name **must** start with `use`, this is just a best practice that if not followed will thrown an error
3 | * it **must** use other Hooks in it and this is what accounts for 'shared logic'
4 |
5 | Create a function is basic JavaScript stuff and something we do each single day, always remember that even if we're using React here a custom Hook is nothing less nothing more than a function.
6 |
7 | So the first thing we do to solve our problem is to create the function that will contain the shared logic:
8 | ```js
9 | function useLocalStorageState(){
10 | // Shared logic
11 | }
12 | ```
13 | Once we have the function we need to start thinking about the logic that we want to put in it.
14 |
15 | As highlighted a custom Hook has to use other build-in Hooks in order to be one. For example, if you need to wrap the logic that is getting a value and stores it in `localStorage` we can write something like this:
16 | ```js
17 | function useLocalStorageState(key, defaultValue = '') {
18 | const [state, setState] = React.useState(
19 | () => window.localStorage.getItem(key) ||
20 | defaultValue,
21 | )
22 | React.useEffect( () => {
23 | window.localStorage.setItem(key, state)
24 | }, [key, state] )
25 |
26 | return [ state, setState ]
27 | }
28 | ```
29 | As we can see this custom Hook `useLocalStorageState` gets two parameters:
30 | * a `key` that will identify the value stored in `localStorage`
31 | * a `defaultValue` that we initialize with an empty string and will identify the value that we need to store in `localStorage` for the specified string
32 |
33 | Note that this custom Hook is behaving similarly to the built-in [[React.useState()|useState]] Hook since is returning an array where the first value is the actual value of the state and the second one is the updater fn.
34 |
35 | Once this custom Hook is in place and imported within our component we can start to use it as follow:
36 | ```js
37 | // State with localStorage for the name
38 | const [name, setName] = useLocalStorageState('name', 'Andrea')
39 | // State with localStorage for the age
40 | const [age, setAge] = useLocalStorageState('name', 37)
41 | ```
42 | ### Other examples
43 | ...
--------------------------------------------------------------------------------
/React/key prop.md:
--------------------------------------------------------------------------------
1 | The `key` prop is a special functionality in React that helps the library understand what has changed in a generated JSX. I am talking about generated JSX because the following list are different even if the output HTML looks the same.
2 | ```js
3 | // Assume we are inside a component
4 |
5 | // I am returning a full list
6 | return (
7 |
8 | - One
9 | - Two
10 | - Three
11 |
12 | );
13 |
14 | // I am generating the list of li elements with .map() that generates a new array
15 | const elements = [ 'One', 'Two', 'Three' ];
16 |
17 | {elements.map( el => - {el}
)}
18 |
19 | ```
20 | The main difference here is that for React the first example is just a [[React.createElement()]] with HTML in it instead the second one is an array that generates an element, calls [[React.createElement()]], for each item.
21 |
22 | In order to help React know which element we are working with is always a best idea to add an unique `key` prop that also helps it increase the performances of our code, besides removing some silly errors when React guess badly 😉
23 |
24 | When using `key` prop is best practice **not use an index** because need to be consistent for the component for the component that React is tracking, the index of an array follows the position of an item and that's means that different value can have the same position between renders based on how we remove/add the data in the array.
--------------------------------------------------------------------------------