# The Road to Learn React

## Metadata
- Author: [[Robin Wieruch]]
- Full Title: The Road to Learn React
- Category: #books
## Highlights
- In the past, websites and web applications were rendered from the server. A user visits a URL in a browser and requests one HTML file and all its associated HTML, CSS, and JavaScript files from a web server. After some network delay, the user sees the rendered HTML in the browser (client) and starts to interact with it. Every additional page transition (meaning: visiting another URL) would initiate this chain of events again. In this version from the past, essentially everything crucial is done by the server, whereas the client plays a minimal role by just rendering page by page. ([Location 144](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=144))
- Tags: [[blue]]
- modern JavaScript shifted the focus from the server to the client. The most extreme version of it: A user visits a URL and requests one small HTML file and one larger JavaScript file. After some network delay, the user sees the by JavaScript rendered HTML in the browser and starts to interact with it. Every additional page transition wouldn’t request more files from the web server, but would use the initially requested JavaScript to render the new page. Also, every additional interaction by the user is handled on the client too. In this modern version, the server delivers mainly JavaScript across the wire with one minimal HTML file. The HTML file then executes all the linked JavaScript from the files on the client-side to render the entire application with HTML and uses JavaScript for its interactions. React, among the other SPA solutions, makes this possible. ([Location 150](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=150))
- Tags: [[blue]]
- A component has to start with a capital letter, otherwise it isn’t treated as component in React. The kind of the App component is commonly called a function component. Function components are the modern way of using components in React, however, be aware that there are other variations of React components ([Location 342](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=342))
- Tags: [[blue]]
- The function of a component runs every time a component is displayed in the browser. This happens for the initial rendering (read: displaying) of the component, but also whenever the component updates because it has to display something different due to changes (re-rendering). ([Location 359](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=359))
- Tags: [[blue]]
- On your journey as a React developer, and in this learning experience, you will come across both scenarios: variables (and functions) defined outside and within a component. As a rule of thumb: If a variable does not need anything from within the function component’s body (e.g. parameters), then define it outside of the component which avoids re-defining it on every function call. ([Location 368](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=368))
- Tags: [[blue]]
- When using HTML in JSX, React internally translates all HTML attributes to JavaScript where certain words such as class or for are reserved during the rendering process. Therefore React came up with replacements such as className and htmlFor for them. However, once the actual HTML is rendered for the browser, the attributes get translated back to their native variant. ([Location 405](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=405))
- Tags: [[blue]]
- JSX enables developers to express what should be rendered by mixing up HTML with JavaScript. Whereas the previous way of thinking was to decouple markup (read: HTML) from logic (read: JavaScript), React puts all of it together as one unit in a React component. ([Location 446](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=446))
- Tags: [[blue]]
- Linting is a process in programming where code is analyzed for potential errors, bugs, and style issues. It is an important step in the cycle of software development as it helps to identify problems early on and improves the overall quality of the code. Linting can also enforce specific coding standards, like having or not having always a semicolon at the end of a JavaScript statement, which makes code more consistent and easier to maintain. ([Location 462](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=462))
- Tags: [[blue]]
- We will make the case for using linting (as general programming concept) with ESLint (JavaScript tool for linting) in this section, because it catches errors early. ([Location 469](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=469))
- Tags: [[blue]]
- Actually, rendering a list of items in React was one of my personal JSX “Aha” moments. Without any made up templating syntax, it’s possible to use JavaScript to map from a list of items to a list of HTML elements. That’s what JSX is for the developer in the end: just JS mixed with HTML. ([Location 556](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=556))
- Tags: [[blue]]
- The key attribute is used for one specific reason: Whenever React has to re-render a list, it checks whether an item has changed. When using keys, React can efficiently exchange the changed items. When not using keys, React may update the list inefficiently. ([Location 568](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=568))
- Tags: [[blue]]
- React applications have component hierarchies (also called component trees). There is usually one uppermost entry point component (e.g. App) that spans a tree of components below it. The App is the parent component of the List and Search, so the List and Search are child components of the App component and sibling components to each other. The illustration takes it one step further where the Item component is a child component of the List. In a component tree, there is always a root component (e.g. App), and the components that don’t render any other components are called leaf components (e.g. List/Search component in our current source code or Item/Search component from the illustration). All components can have zero, one, or many child components. ([Location 649](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=649))
- Tags: [[blue]]
- Usually you will start out with the App component from where you grow your component tree. Either you know the components you wanna create beforehand or you start with one component and extract components from it eventually. For a beginner, it may be difficult to know when to create a new component or when to extract a component from another component. Usually it happens naturally whenever a component gets too big in size/complexity or whenever you see natural boundaries in domains/functionality (e.g. List component renders a list of items, Search component renders a search form). ([Location 656](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=656))
- Tags: [[blue]]
- In the end, each component represents a single unit in your application which makes the application maintainable and predictable. ([Location 660](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=660))
- Tags: [[pink]]
- While React is used for the day to day business of a React developer, React DOM is usually used once in a React application to hook React into the native HTML world. Open the index.html file on the side and spot the HTML element where the id attribute equals "root". That’s exactly the element where React inserts itself into the HTML to bootstrap the entire React application – starting with the App component. ([Location 739](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=739))
- Tags: [[blue]]
- In the JavaScript file, the createRoot() method expects the HTML element that is used to instantiate React. There we are using JavaScript’s built-in getElementById() method to return the HTML element that we have seen in the index.html file. Once we have the root object, we can call render() on the returned root object with JSX as parameter which usually represents the entry point component (also called root component). Normally the entry point component is the instance of the App component, but it can be any other JSX too: ([Location 742](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=742))
- Tags: [[blue]]
- Essentially React DOM is everything that’s needed to integrate React into any website which uses HTML. If you start a React application from scratch, there is usually only one ReactDOM.createRoot() call in your application. However, if you happen to work on a legacy application that used something else than React before, you may see multiple ReactDOM.createRoot() calls, because only certain areas of the application are powered by React. ([Location 753](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=753))
- Tags: [[blue]]
- As a rule of thumb, use either function declarations or arrow function expressions for your component declarations throughout your application. Both versions are fine to use, but make sure that you and your team working on the project share the same implementation style. In addition, while an implicit return statement when using an arrow function expressions makes your component declaration more concise, you may introduce tedious refactorings from concise to block body when you need to perform tasks between function signature and the return statement. So you may want to keep your arrow function expression with a block body (like in the last code snippet) all the time. ([Location 818](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=818))
- Tags: [[blue]]
- React’s synthetic event is essentially a wrapper around the browser’s native event. Since React started as library for single-page applications, there was the need for enhanced functionalities on the event to prevent the native browser behavior. ([Location 850](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=850))
- Tags: [[blue]]
- if you happen to need access to the native HTML event, you could do so by using event.nativeEvent, but after several years of React development I never ran into this case myself. ([Location 853](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=853))
- Tags: [[blue]]
- This could work if you only had one global variable, but it isn’t maintainable with multiple variables across multiple components (within multiple folders/files). By using so-called props in React, we can pass variables as information from one component to another component. ([Location 877](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=877))
- Tags: [[blue]]
- Everything that we pass from a parent component to a child component via the component element’s HTML attribute can be accessed in the child component. The child component receives a parameter (props) as object in its function signature which includes all the passed attributes as properties (short: props). ([Location 901](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=901))
- Tags: [[blue]]
- The most important fact about props: it’s not allowed to change them, because they should be treated as an immutable data structure. They are only used to pass information down the component hierarchy. Continuing this thought, information (props) can only be passed from a parent to a child component and not vice versa. ([Location 920](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=920))
- Tags: [[blue]]
- React state introduces a mutable data structure (read: stateful values). These stateful values get instantiated in a React component as so called state, can be passed with props as vehicle down to child components, but can also get mutated by using a function to modify the state. When a state gets mutated, the component with the state and all child components will re-render. ([Location 929](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=929))
- Tags: [[blue]]
- Both concepts, props and state, have clear defined purposes: While props are used to pass information down the component hierarchy, state is used to change information over time. ([Location 933](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=933))
- Tags: [[blue]]
- By using useState, we are telling React that we want to have a stateful value which changes over time. And whenever this stateful value changes, the affected components (here: Search component) will re-render to use it (here: to display the recent value). ([Location 949](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=949))
- Tags: [[blue]]
- It’s important to note that the useState function is called a React hook. ([Location 967](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=967))
- Tags: [[blue]]
- Whenever the UI is re-rendered because of a state change, the useState hook uses the most recent state from its internal closure. This might seem odd, as one would assume the useState gets declared from scratch every time a component’s function runs. However, next to each component React allocates an object where information like state is stored in memory. Eventually the memory gets cleaned up once a component is not rendered anymore through JavaScript’s garbage collection. ([Location 972](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=972))
- Tags: [[blue]]
- There is no way to pass information up the component tree, since props are naturally only passed downwards. However, we can introduce a callback handler instead: A callback handler gets introduced as event handler (A), is passed as function in props to another component (B), is executed there as callback handler (C), and calls back to the place it was introduced (D): ([Location 990](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=990))
- Tags: [[blue]]
- The concept of the callback handler in a nutshell: We pass a function from a parent component (App) to a child component (Search) via props; we call this function in the child component (Search), but have the actual implementation of the called function in the parent component (App). In other words, when an (event) handler is passed as props from a parent component to its child component, it becomes a callback handler. React props are always passed down the component tree and therefore functions that are passed down as callback handlers in props can be used to communicate up the component tree. ([Location 1006](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=1006))
- Tags: [[blue]]
- Rule of thumb: Always manage state at a component level where every component that’s interested in it is one that either manages the state (using information directly from state, e.g. App component) or a component below the state managing component (using information from props, e.g. List or Search components). If a component below needs to update the state (e.g. Search), pass a callback handler down to it which allows this particular component to update the state above in the parent component. If a component below needs to use the state (e.g. displaying it), pass it down as props. ([Location 1042](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=1042))
- Tags: [[blue]]
- When refactoring a component, always aim for readability, especially when working in a team of people, and make sure everyone is using a common React code style. ([Location 1314](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=1314))
- Tags: [[blue]]
- Rules of thumb: Always use object destructuring for props in a function component’s function signature, because props are rarely used themselves. Exception: When props are only passed through the component to the next child component (see when to use spread operator). Use the spread operator when you want to pass all key/value pairs of an object to a child component in JSX. For example, often props themselves are not used in a component but only passed along to the next component. Then it makes sense to just spread the props object {...props} to the next component. Use the rest operator when you only want to split out certain properties from your props object. Use nested destructuring only when it improves readability. ([Location 1316](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=1316))
- Tags: [[blue]]
- React’s useEffect Hook takes two arguments: The first argument is a function that runs our side-effect. In our case, the side-effect stores searchTerm into the browser’s local storage. The second argument is a dependency array of variables. If one of these variables changes, the function for the side-effect is called. In our case, the function is called every time the searchTerm changes (e.g. when a user types into the HTML input field). In addition, it’s also called initially when the component renders for the first time. ([Location 1375](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=1375))
- Tags: [[blue]]
- A custom hook can encapsulate non-trivial implementation details that should be kept away from a component, can be used in more than one React component, can be a composition of other hooks, and can even be open-sourced as an external library. Using your favorite search engine, you’ll notice there are hundreds of React hooks that could be used in your application without worry over implementation details. ([Location 1448](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=1448))
- Tags: [[blue]]
- A fragment wraps sibling elements into a single top-level element without adding them to the rendered output. ([Location 1486](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=1486))
- Tags: [[blue]]
- Conditional rendering is not just for asynchronous data though. The simplest example of conditional rendering is a boolean state that’s toggled with a button. If the boolean flag is true, render something, if it is false, don’t render anything. Knowing about this feature in React can be quite powerful, because it gives you the ability to conditionally render JSX. ([Location 1869](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=1869))
- Tags: [[blue]]
- React’s useReducer Hook enables one to use more sophisticated state management for complex state structures and transitions. ([Location 1884](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=1884))
- Tags: [[blue]]
- Using useReducer over useState makes sense as soon as multiple stateful values are dependent on each other or related to one domain. For example, stories, isLoading, and error are all related to the data fetching. In a more abstract version, all three could be properties in a complex object (e.g. data, isLoading, error) managed by a reducer instead. ([Location 1888](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=1888))
- Tags: [[blue]]
- Instead of setting the state explicitly with the state updater function from useState, the useReducer state updater function sets the state implicitly by dispatching an action for the reducer. The action comes with a type and an optional payload: ([Location 1910](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=1910))
- Tags: [[blue]]
- There is nothing wrong with multiple useState hooks in one React component. Be wary once you see multiple state updater functions in a row, however. These conditional states can lead to impossible states and undesired behavior in the UI. ([Location 1962](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=1962))
- Tags: [[blue]]
- we can improve our chances of not dealing with such bugs by moving states that belong together from multiple useState (and useReducer) hooks into a single useReducer hook. ([Location 1974](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=1974))
- Tags: [[blue]]
- React’s useCallback Hook creates a memoized function every time its dependency array (E) changes. As a result, the useEffect hook runs again (C), because it depends on the new function (D): ([Location 2171](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=2171))
- Tags: [[blue]]
- The advantage of CSS modules is that we receive an error in JavaScript each time a style isn’t defined. In the standard CSS approach, unmatched styles in JavaScript and CSS files might go unnoticed. ([Location 2830](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=2830))
- Tags: [[blue]]
- CSS-in-JS with styled components shifts the focus of defining styles to actual React components. Styled Components are styles defined as React components without the intermediate CSS file. If a styled component isn’t used in a JavaScript, your IDE/editor will tell you. Styled Components are bundled next to other JavaScript assets in JavaScript files for a production-ready application. There are no extra CSS files, but only JavaScript when using the CSS-in-JS strategy. Both strategies, CSS-in-JS and CSS-in-CSS, and their approaches (e.g. Styled Components and CSS Modules) are popular among React developers. Use what suits you and your team best. ([Location 2939](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=2939))
- Tags: [[blue]]
- React’s Strict Mode is a helper component which notifies developers in the case of something being wrong in our implementation. For example, using a deprecated React API (e.g. using a legacy React hook) would give us a warning in the browser’s developer tools. However, it also ensures that state and side-effects are implemented well by a developer. ([Location 3037](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=3037))
- Tags: [[blue]]
- This is React’s default behavior, re-rendering everything below a component (here: the App component) with a state change, which surprises many people. In other words, if a parent component re-renders, its descendent components re-render as well. React does this by default, because preventing a re-render of child components could lead to bugs. ([Location 3133](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=3133))
- Tags: [[blue]]
- While all props passed to a component stay the same, the component renders again if its parent component is forced to re-render. That’s React’s default behavior, which works most of the time because the re-rendering mechanism is pretty fast. However, if re-rendering decreases the performance of a React application, React’s memo API helps prevent re-rendering. As we have seen, sometimes memo alone doesn’t help, though. Callback handlers are re-defined each time in the parent component and passed as changed props to the component, which causes another re-render. In that case, useCallback is used for making the callback handler only change when its dependencies change. ([Location 3161](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=3161))
- Tags: [[blue]]
- If all arguments are passed to a function, it’s acceptable to have it outside the component, because it does not have any further dependency needed from within the component. This prevents creating the function on every render, so the useCallback hook becomes unnecessary. ([Location 3177](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=3177))
- Tags: [[blue]]
- Now, after we went through these scenarios for useMemo, useCallback, and memo, remember that these shouldn’t necessarily be used by default. Apply these performance optimizations only if you run into performance bottlenecks. Most of the time this shouldn’t happen, because React’s rendering mechanism is pretty efficient by default. Sometimes the check for utilities like memo can be more expensive than the re-rendering itself. ([Location 3191](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=3191))
- Tags: [[blue]]
- Instead of getting type errors on runtime on the command line or browser, TypeScript integration presents them during compile time inside the IDE. It shortens the feedback loop for a developer, while it improves the developer experience. In addition, the code becomes more self-documenting and readable, because every variable is defined with a type. Also moving code blocks or performing a larger refactoring of a codebase becomes much more efficient. ([Location 3206](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=3206))
- Tags: [[blue]]
- This test still fails because we are using toBe instead of toStrictEqual. The toBe assertive function makes a strict comparison like newState === expectedState. The content of the objects are the same, however, their object references are not the same. We use toStrictEqual instead of toBe to limit our comparison to the object’s content: ([Location 3558](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=3558))
- Tags: [[blue]]
- Remember, a reducer function will always follow the same test pattern: given a state and action, we expect the following new state. Every action of the reducer could be another test case in our reducer’s test suite, so consider using the exercises as a way to move through your entire source code. ([Location 3572](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=3572))
- Tags: [[blue]]
- Both, getByText and getByRole are RTL’s most widely used search functions. We can continue here by asserting not only that everything is in the document, but also by asserting whether our events work as expected. For example, the Item component’s button element can be clicked and we want to verify that the callback handler gets called. ([Location 3677](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=3677))
- Tags: [[blue]]
- Vitest lets us pass a test-specific function to the Item component as a prop. These test-specific functions are called spy, stub, or mock; each is used for different test scenarios. The vi.fn() returns us a mock for the actual function, which lets us capture when it’s called. As a result, we can use Vitest’s assertions like toHaveBeenCalledTimes, which lets us assert a number of times the function has been called; and toHaveBeenCalledWith, to verify arguments that are passed to it. ([Location 3690](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=3690))
- Tags: [[blue]]
- The getByLabelText search function allows us to find an element by a label in a form. This is useful for components that render multiple labels and HTML controls. However, you may have noticed we used a regular expression here. If we used a string instead, the colon for “Search:” must be included. By using a regular expression, we are matching strings that include the “Search” string, which makes finding elements much more efficient. For this reason, you may find yourself using regular expressions instead of strings quite often. ([Location 3725](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=3725))
- Tags: [[blue]]
- There may be some confusion about when to use getBy or the queryBy search variants. As a rule of thumb, use getBy for single elements, and getAllBy for multiple elements. If you are checking for elements that aren’t present, use queryBy (or queryAllBy). In this code, I preferred using queryBy for the sake of alignment and readability. ([Location 3811](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=3811))
- Tags: [[blue]]
- React Testing Library with Vitest is the most popular library combination for React testing. RTL provides relevant testing tools, while Vitest has a general testing framework for test suites, test cases, assertions, and mocking capabilities. If you need an alternative to RTL, consider trying Enzyme by Airbnb. ([Location 3887](https://readwise.io/to_kindle?action=open&asin=B077HJFCQX&location=3887))
- Tags: [[blue]]