├── .DS_Store ├── .gitattributes ├── .gitignore ├── README.md ├── babel.config.js ├── blog ├── 2023-07-31-welcome.md └── authors.yml ├── docs ├── Hooks │ ├── Introduction.md │ ├── useCallback.md │ ├── useContext.md │ ├── useEffect.md │ ├── useMemo.md │ ├── useReducer.md │ ├── useRef.md │ ├── useState.md │ └── useTransition.md ├── basics.md ├── batching.md ├── error-boundary.md ├── immutability.md ├── introduction.md ├── proptypes.md ├── react-children.md ├── react-fragments.md ├── react-lazy.md ├── react-memo.md ├── react-props.md ├── react-refs.md ├── react-terms.md └── reconciliation.md ├── docusaurus.config.js ├── package-lock.json ├── package.json ├── sidebars.js ├── src ├── components │ └── HomepageFeatures │ │ ├── index.js │ │ └── styles.module.css ├── css │ └── custom.css └── pages │ ├── index.js │ └── index.module.css └── static ├── .nojekyll └── img ├── code_review.svg ├── code_snippets.svg ├── docusaurus-social-card.jpg ├── docusaurus.png ├── favicon.ico ├── logo.png ├── personal_notebook.svg ├── react_i.svg ├── undraw_docusaurus_mountain.svg ├── undraw_docusaurus_react.svg └── undraw_docusaurus_tree.svg /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mutasim77/ReactJS-Notebook/68d78c13588845b149af6e080a9ee7e30c975fe1/.DS_Store -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.md linguist-detectable=false 2 | *.mdx linguist-detectable=false 3 | *.css linguist-detectable=false 4 | 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | /node_modules 3 | 4 | # Production 5 | /build 6 | 7 | # Generated files 8 | .docusaurus 9 | .cache-loader 10 | 11 | # Misc 12 | .DS_Store 13 | .env.local 14 | .env.development.local 15 | .env.test.local 16 | .env.production.local 17 | 18 | npm-debug.log* 19 | yarn-debug.log* 20 | yarn-error.log* 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## ReactJS Notebook 📒: Your Gateway to Learning and Mastering React 🚀 2 | In my humble opinion, learning is closely intertwined with taking notes. I firmly believe that if you're not taking notes, you're missing out on a powerful learning tool. Whether it's jotting things down on paper or going digital, notes serve as a bridge between what you're learning and your future reference. 📝 3 | 4 | My journey with ReactJS started much the same way. As I delved into the intricacies of this powerful JavaScript library, I realized the importance of keeping a record of what I learned. Why? Because React is a dynamic and complex framework with numerous concepts, components, and best practices. I wanted a way to capture and retain this wealth of knowledge, and that's where my ReactJS Notebook was born. 💡 5 | 6 | ## From Markdown Repository to a User-Friendly Website 🌐 7 | Initially, my ReactJS Notebook was nothing more than a repository containing notes in Markdown format. While Markdown is a fantastic way to structure content, it lacked the user-friendly interface I desired. My goal was to create a resource that's not only informative but also engaging and easy to navigate. 8 | 9 | So, I took the leap and transformed my Markdown repository into a full-fledged website. The result? A platform that boasts a clean and intuitive user interface, designed to make your learning experience more interesting and enjoyable. 📱 10 | 11 | ***Check It Out:*** ReactJS Notebook 📒 12 | 13 | **Here's a screenshot of the website:** 14 | Screenshot 15 | 16 | ## Your Support Matters 🌟 17 | If you find ReactJS Notebook to be a helpful resource in your learning journey, I'd truly appreciate your support. Give it a star on GitHub to show your appreciation and encourage further development. Every star is a testament to the value it provides. ⭐ 18 | 19 | ## Make It Your Own 🛠️ 20 | ReactJS Notebook is open to the community. You can use this website as a starting point and customize it to fit your own learning needs. Adapt and expand upon it, or contribute your own insights and notes to help others on their ReactJS journey. 21 | 22 | Thank you for joining me in this learning adventure, and I hope ReactJS Notebook becomes a valuable companion in your quest to master React. 23 | 24 | Happy coding! ❤️ 25 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [require.resolve('@docusaurus/core/lib/babel/preset')], 3 | }; 4 | -------------------------------------------------------------------------------- /blog/2023-07-31-welcome.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: welcome 3 | title: Welcome 4 | authors: [mutasim] 5 | tags: [life] 6 | --- 7 | 8 | To the person reading this: I understand that it may be difficult, but never give up ! 9 | -------------------------------------------------------------------------------- /blog/authors.yml: -------------------------------------------------------------------------------- 1 | mutasim: 2 | name: Mutasim 3 | title: Frontend Dev 4 | url: https://github.com/mutasim77/ 5 | image_url: https://github.com/mutasim77.png 6 | -------------------------------------------------------------------------------- /docs/Hooks/Introduction.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: react-hooks 3 | title: Introduction 4 | description: Quick introduction 5 | sidebar_position: 1 6 | --- 7 | 8 | import DocCardList from '@theme/DocCardList'; 9 | import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; 10 | 11 | # React Hooks 🎣 12 | 13 | React Hooks are a powerful feature introduced in React 16.8 that allows developers to add state and other React features to functional components. Prior to the introduction of hooks, state management and other complex logic could only be implemented in class components using lifecycle methods. With hooks, developers can now write more concise and reusable code by leveraging functions instead of classes. 14 | 15 | Hooks provide several benefits in React development. Firstly, they simplify the management of component state. With the "useState" hook, you can add state to a functional component, eliminating the need for a class-based component. This results in cleaner and more readable code. 16 | 17 | Secondly, hooks enable the reuse of logic across components. The "useEffect" hook allows you to perform side effects such as data fetching, subscriptions, or manually changing the DOM after rendering. By encapsulating such logic in a custom hook, you can easily share it across different components, improving code maintainability and reducing duplication. 18 | 19 | Another advantage of hooks is the ability to create custom hooks. Custom hooks are functions that combine multiple built-in hooks and encapsulate complex logic into reusable units. This promotes code modularity and makes it easier to share code between projects or within a team. 20 | 21 | Here is a list of some commonly used React hooks: 22 | 23 | 24 | 25 | These hooks cover a wide range of functionality and help streamline the development process in React. 26 | -------------------------------------------------------------------------------- /docs/Hooks/useCallback.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: react-hook-useCallback 3 | title: useCallback 4 | description: Memoizes a function to prevent unnecessary re-rendering of components that depend on it. 5 | sidebar_position: 4 6 | --- 7 | 8 | **useCallback** is a React hook that allows you to optimize the performance of your React components by memoizing a function. In simple terms, it helps you avoid unnecessary re-creation of functions on each render. 9 | 10 | When you define a function inside a component, it gets recreated every time the component re-renders, even if the function itself hasn't changed. This can lead to performance issues, especially if you pass that function as a prop to child components, as it may cause unnecessary re-renders in those components too. 11 | 12 | Here's where useCallback comes in handy. It memoizes a function and returns a memoized version of it. The memoized version will only change if any of the dependencies provided to useCallback change. If the dependencies remain the same, useCallback will return the same memoized function from the previous render. 13 | 14 | Here's an example to illustrate its usage: 15 | 16 | ```jsx 17 | import React, { useState, useCallback } from 'react'; 18 | 19 | const CounterButton = ({ onClick }) => { 20 | console.log('CounterButton rendering'); 21 | return ( 22 | 25 | ); 26 | }; 27 | 28 | const Counter = () => { 29 | const [count, setCount] = useState(0); 30 | 31 | const handleClick = useCallback(() => { 32 | setCount(count + 1); 33 | }, [count]); 34 | 35 | console.log('Counter rendering'); 36 | 37 | return ( 38 |
39 |

Count: {count}

40 | 41 |
42 | ); 43 | }; 44 | ``` 45 | 46 | In the example above, we have a Counter component that renders a CounterButton component. Whenever the Counter component re-renders, it will create a new handleClick function because it references the count state value. However, by using **useCallback**, we can optimize this behavior. 47 | 48 | By providing [count] as the dependency array to useCallback, it ensures that the handleClick function will only be re-created if the count value changes. If count remains the same, useCallback will return the previously memoized handleClick function. 49 | 50 | This optimization can be helpful when passing handleClick as a prop to child components because it prevents unnecessary re-renders in those components if the dependencies haven't changed. 51 | 52 | Remember to include all the dependencies that the function relies on in the dependency array to ensure the correct behavior of **useCallback**. -------------------------------------------------------------------------------- /docs/Hooks/useContext.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: react-hook-useContext 3 | title: useContext 4 | description: Lets you read and subscribe to context from your component. 5 | sidebar_position: 8 6 | --- 7 | 8 | React context provides data to components no matter how deep they are in the components tree. The context is used to manage global data, e.g. global state, theme, services, user settings, and more. 9 | 10 | ## How to use the context ? 🤓 11 | Using the context in React requires 3 simple steps: creating the context, providing the context, and consuming the context. 12 | 13 | - A. Creating the context 14 | 15 | The built-in factory function createContext(default) creates a context instance: 16 | 17 | ```jsx 18 | // context.js 19 | import { createContext } from 'react'; 20 | 21 | export const Context = createContext('Default Value'); 22 | ``` 23 | 24 | The factory function accepts one optional argument: the **default** value. 25 | 26 | - B. Providing the context 27 | 28 | **Context.Provider** component available on the context instance is used to provide the context to its child components, no matter how deep they are. 29 | 30 | To set the value of context use the **value** prop available on the `` : 31 | 32 | ```jsx 33 | import { Context } from './context'; 34 | 35 | function Main() { 36 | const value = 'My Context Value'; 37 | return ( 38 | 39 | 40 | 41 | ); 42 | } 43 | ``` 44 | 45 | Again, what's important here is that all the components that'd like later to consume the context have to be wrapped inside the provider component. 46 | 47 | If you want to change the context value, simply update the value prop. 48 | 49 | - C. Consuming the context 50 | 51 | Consuming the context can be performed in 2 ways. 52 | 53 | The first way, the one I recommend, is to use the ```useContext(Context)``` React hook: 54 | 55 | ```jsx 56 | import { useContext } from 'react'; 57 | import { Context } from './context'; 58 | 59 | function MyComponent() { 60 | const value = useContext(Context); 61 | 62 | return {value}; 63 | } 64 | ``` 65 | 66 | The hook returns the value of the context: `value = useContext(Context)`. The hook also makes sure to re-render the component when the context value changes. 67 | 68 | The second way is by using a render function supplied as a child to Context.Consumer special component available on the context instance: 69 | 70 | ```jsx 71 | import { Context } from './context'; 72 | 73 | function MyComponent() { 74 | return ( 75 | 76 | {value => {value}} 77 | 78 | ); 79 | } 80 | ``` 81 | 82 | Again, in case the context value changes, `` will re-call its render function. 83 | 84 | ![useContext pic](https://github.com/mutasim77/ReactJS-Notebook/assets/96326525/ec4f7e4c-24e4-49ee-96b3-a7f4b6f2d8cd) 85 | 86 | You can have as many consumers as you want for a single context. If the context value changes "by changing the value prop of the provider ``", then all consumers are immediately notified and re-rendered. 87 | 88 | If the consumer isn't wrapped inside the provider, but still tries to access the context value using `useContext(Context)` or `*`*, then the value of the context would be the default value argument supplied to `*createContext(defaultValue)*` factory function that had created the context. 89 | 90 | ## When do you need context? 🤓 91 | 92 | The main idea of using the context is to allow your components to access global data and re-render when that global data is changed. Context solves the props drilling problem: when you have to pass down props from parents to children. 93 | 94 | You can hold inside the context: 95 | 96 | - global state 97 | - theme 98 | - application configuration 99 | - authenticated user name 100 | - user settings 101 | - preferred language 102 | - a collection of services 103 | 104 | On the other side, you should think carefully before deciding to use context in your application. 105 | 106 | First, integrating the context adds complexity. Creating a context, wrapping everything in a provider, and using the useContext() in every consumer — increases complexity. 107 | 108 | Secondly, adding context complicates unit testing of components. During testing, you'll have to wrap the consumer components into a context provider. Including the components that are indirectly affected by the context — the ancestors of context consumers! 109 | 110 | ## Conclusion 🤓 111 | The context in React lets you supply child components with global data, no matter how deep they are in the components tree. 112 | 113 | Using the context requires 3 steps: creating, providing, and consuming the context. 114 | 115 | When integrating the context into your application, consider that it adds a good amount of complexity. Sometimes drilling the props through 2-3 levels in the hierarchy isn't a big problem. -------------------------------------------------------------------------------- /docs/Hooks/useEffect.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: react-hook-useEffect 3 | title: useEffect 4 | description: Performs side effects after rendering, such as data fetching or subscriptions. 5 | sidebar_position: 3 6 | --- 7 | 8 | *useEffect* is a hook in React that allows you to perform side effects in functional components. Side effects can include things like fetching data from an API, subscribing to events, or updating the document title. It's called a "side effect" because it doesn't directly affect the rendering of your component, but rather deals with other interactions outside of it. 9 | 10 | Here's a breakdown of how to use useEffect: 11 | 12 | Import the useEffect hook from the React library: 13 | 14 | ```jsx 15 | import React, { useEffect } from 'react'; 16 | ``` 17 | Use the useEffect hook inside your functional component: 18 | 19 | ```jsx 20 | function MyComponent() { 21 | useEffect(() => { 22 | // Side effect code goes here 23 | }); 24 | 25 | return ( 26 | // JSX code for your component 27 | ); 28 | } 29 | ``` 30 | 31 | The first argument of useEffect is a function that will be called after the component renders. This function is where you can place your side effect code. It runs every time the component renders by default. 32 | 33 | ```jsx 34 | useEffect(() => { 35 | // Side effect code 36 | }); 37 | ``` 38 | 39 | You can also provide a second argument to useEffect that determines when the effect should run. This is an optional array of dependencies. If any of the dependencies change between renders, the effect will be triggered again. If the dependency array is empty, the effect will only run once when the component mounts, and not again. 40 | 41 | ```jsx 42 | useEffect(() => { 43 | // Side effect code 44 | }, [dependency1, dependency2]); 45 | ``` 46 | Now let's look at some examples: 47 | 48 | 1. Fetching data from an API: 49 | ```jsx 50 | useEffect(() => { 51 | fetch('https://api.example.com/data') 52 | .then(response => response.json()) 53 | .then(data => { 54 | // Do something with the fetched data 55 | }); 56 | }, []); 57 | ``` 58 | In this example, the effect runs only once when the component mounts because the dependency array is empty. 59 | 60 | 2. Subscribing to an event: 61 | ```jsx 62 | useEffect(() => { 63 | const handleClick = () => { 64 | // Handle the click event 65 | }; 66 | 67 | window.addEventListener('click', handleClick); 68 | 69 | return () => { 70 | window.removeEventListener('click', handleClick); 71 | }; 72 | }, []); 73 | ``` 74 | Here, the effect adds an event listener for the click event when the component mounts, and removes it when the component unmounts. The empty dependency array ensures that the effect only runs once. 75 | 76 | -------------------------------------------------------------------------------- /docs/Hooks/useMemo.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: react-hook-useMemo 3 | title: useMemo 4 | description: Memoizes a value to prevent expensive computations on every render. 5 | sidebar_position: 5 6 | --- 7 | 8 | **useMemo** is another React hook that allows you to optimize the performance of your React components by memoizing a value. It's similar to **useCallback**, but instead of memoizing a function, it memoizes a computed value. 9 | 10 | In React, there are situations where you may have expensive computations or calculations that are performed within a component. These computations can take up processing power and slow down your application, especially if they are re-executed on every render, even if the dependencies haven't changed. 11 | 12 | Here's where useMemo comes in handy. It allows you to memoize the result of a computation and only recompute it if the dependencies provided to useMemo have changed. If the dependencies remain the same, useMemo will return the previously memoized value from the previous render, saving unnecessary calculations. 13 | 14 | Here's an example to illustrate its usage: 15 | 16 | ```jsx 17 | import React, { useState, useMemo } from 'react'; 18 | 19 | const ExpensiveComponent = ({ value }) => { 20 | const expensiveResult = useMemo(() => { 21 | console.log('Performing expensive computation...'); 22 | // Perform some complex calculations based on the value 23 | return value * 2; 24 | }, [value]); 25 | 26 | console.log('ExpensiveComponent rendering'); 27 | 28 | return ( 29 |
30 |

Value: {value}

31 |

Expensive Result: {expensiveResult}

32 |
33 | ); 34 | }; 35 | 36 | const App = () => { 37 | const [count, setCount] = useState(0); 38 | 39 | const handleClick = () => { 40 | setCount(count + 1); 41 | }; 42 | 43 | console.log('App rendering'); 44 | 45 | return ( 46 |
47 | 48 | 49 |
50 | ); 51 | }; 52 | ``` 53 | 54 | In the example above, we have an **ExpensiveComponent** that performs some computationally expensive calculations based on the value prop it receives. Whenever the **ExpensiveComponent** re-renders, it would recompute the expensive result, even if the value prop hasn't changed. This can impact performance if the calculations are complex. 55 | 56 | By using useMemo, we can optimize this behavior. By providing [value] as the dependency array to useMemo, it ensures that the expensive computation will only be re-executed if the value prop changes. If the value remains the same, useMemo will return the previously memoized value. 57 | 58 | This optimization can be helpful in scenarios where you have expensive computations, heavy data processing, or complex transformations that depend on certain values. By memoizing the result with useMemo, you can avoid unnecessary recalculations and improve the performance of your components. 59 | 60 | Remember to include all the dependencies that the computation relies on in the dependency array to ensure the correct behavior of **useMemo**. 61 | -------------------------------------------------------------------------------- /docs/Hooks/useReducer.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: react-hook-useReducer 3 | title: useReducer 4 | description: Alternative to useState for managing complex state logic. 5 | sidebar_position: 9 6 | --- 7 | 8 | **useReducer** is one of the additional Hooks that shipped with React v16.8. An alternative to the useState Hook, useReducer helps you manage complex state logic in React applications. When combined with other Hooks like **useContext**, **useReducer** can be a good alternative to **Redux, Recoil, or MobX**. In certain cases, it is an outright better option. 9 | 10 | While Redux, Recoil, and MobX are usually the best options for managing global states in large React applications, more often than necessary, many React developers jump into these third-party state management libraries when they could have effectively handled their state with Hooks. 11 | 12 | ### How does the useReducer Hook work? 🤓 13 | 14 | The **useReducer** Hook is used to store and update states, just like the useState Hook. It accepts a reducer function as its first parameter and the initial state as the second. useReducer returns an array that holds the current state value and a dispatch function to which you can pass an action and later invoke it. While this is similar to the pattern Redux uses, there are a few differences. 15 | 16 | For example, the useReducer function is tightly coupled to a specific reducer. We dispatch action objects to that reducer only, whereas in Redux, the dispatch function sends the action object to the store. At the time of dispatch, the components don’t need to know which reducer will process the action. 17 | 18 | For those who may be unfamiliar with Redux, we’ll explore this concept a bit further. There are three main building blocks in Redux: 19 | 20 | - Store: An immutable object that holds the application’s state data 21 | - Reducer: A function that returns some state data, triggered by an action type 22 | - Action: An object that tells the reducer how to change the state. It must contain a type property and can contain an optional payload property 23 | 24 | 25 | Let’s see how these building blocks compare to managing state with the useReducer Hook. Below is an example of a store in Redux: 26 | 27 | ```jsx 28 | import { createStore } from 'redux' 29 | 30 | const store = createStore(reducer, [preloadedState], [enhancer]) 31 | 32 | ``` 33 | 34 | In the code below, we initialize state with the useReducer Hook: 35 | 36 | ```jsx 37 | const initialState = { count: 0 } 38 | 39 | const [state, dispatch] = useReducer(reducer, initialState) 40 | ``` 41 | 42 | **useReducer** doesn’t use the (state = initialState, action) => newState **Redux** pattern, so its reducer function works a bit differently. The code below shows how you’d create reducers with React’s useReducer: 43 | 44 | ```jsx 45 | function reducer(state, action) { 46 | switch (action.type) { 47 | case 'increment': 48 | return {count: state.count + 1}; 49 | case 'decrement': 50 | return {count: state.count - 1}; 51 | default: 52 | throw new Error(); 53 | } 54 | } 55 | ``` 56 | 57 | ### Specifying the initial state 58 | The initial state is the second argument passed to the useReducer Hook, which represents the default state: 59 | 60 | ```jsx 61 | const initialState = { count: 1 } 62 | 63 | // wherever our useReducer is located 64 | const [state, dispatch] = useReducer(reducer, initialState, initFunc) 65 | ``` 66 | 67 | If you don’t pass a third argument to **useReducer**, it will take the second argument as the initial state. The third argument, which is the init function, is optional. This pattern also follows one of the golden rules of Redux state management: the state should be updated by emitting actions. Never write directly to the state. 68 | 69 | However, it’s worth noting that the Redux state = initialState convention doesn’t work the same way with useReducer because the initial value sometimes depends on props. 70 | 71 | ### Creating the initial state lazily 72 | 73 | In programming, lazy initialization is the tactic of delaying the creation of an object, the calculation of a value, or some other expensive process until the first time it is needed. 74 | 75 | As mentioned above, useReducer can accept a third parameter, which is an optional init function for creating the initial state lazily. It lets you extract logic for calculating the initial state outside of the reducer function, as seen below: 76 | 77 | ```jsx 78 | const initFunc = (initialCount) => { 79 | if (initialCount !== 0) { 80 | initialCount=+0 81 | } 82 | return {count: initialCount}; 83 | } 84 | 85 | // wherever our useReducer is located 86 | const [state, dispatch] = useReducer(reducer, initialCount, initFunc); 87 | ``` 88 | 89 | If the value is not 0 already, initFunc above will reset initialCount to 0 on page mount, then return the state object. Notice that this initFunc is a function, not just an array or object. 90 | 91 | ### The dispatch method 92 | 93 | The dispatch function accepts an object that represents the type of action we want to execute when it is called. Basically, it sends the type of action to the reducer function to perform its job, which, of course, is updating the state. 94 | 95 | The action to be executed is specified in our reducer function, which in turn, is passed to the useReducer. The reducer function will then return the updated state. 96 | 97 | The actions that will be dispatched by our components should always be represented as one object with the type and payload key, where type stands as the identifier of the dispatched action and payload is the piece of information that this action will add to the state. dispatch is the second value returned from the useReducer Hook and can be used in our JSX to update the state: 98 | 99 | ```jsx 100 | // creating our reducer function 101 | function reducer(state, action) { 102 | switch (action.type) { 103 | // ... 104 | case 'reset': 105 | return { count: action.payload }; 106 | default: 107 | throw new Error(); 108 | } 109 | } 110 | 111 | // wherever our useReducer is located 112 | const [state, dispatch] = useReducer(reducer, initialCount, initFunc); 113 | 114 | // Updating the state with the dispatch functon on button click 115 | 116 | ``` 117 | 118 | Notice how our reducer function uses the payload that is passed from the dispatch function. It sets our state object to the payload, i.e., whatever the initialCount is. Note that we can pass the dispatch function to other components through props, which alone is what allow us to replace Redux with useReducer. 119 | 120 | Let’s say we have a component that we want to pass as props to our dispatch function. We can easily do that from the parent component: 121 | 122 | ```jsx 123 | dispatch({type: 'increment'})}/> 124 | ``` 125 | 126 | Now, in the child component, we receive the props, which, when emitted, will trigger the dispatch function and update the state: 127 | 128 | ```jsx 129 | 130 | ``` 131 | 132 | ### When not to use the useReducer Hook 133 | Despite being able to use the useReducer Hook to handle complex state logic in our app, it’s important to note that there are some scenarios where a third-party state management library like **Redux** may be a better option: 134 | 135 | - When your application needs a single source of truth 136 | - When you want a more predictable state 137 | - When state-lifting to the top-level component no longer suffices 138 | - When you need to persist state even after a page refresh 139 | 140 | With all these benefits, it’s also worth noting that using a library like Redux, as opposed to using pure React with useReducer, comes with some tradeoffs. For example, Redux has a hefty learning curve that is minimized by using **Redux Toolkit**, and it’s definitely not the fastest way to write code. Rather, it’s intended to give you an absolute and predictable way of managing state in your app. -------------------------------------------------------------------------------- /docs/Hooks/useRef.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: react-hook-useRef 3 | title: useRef 4 | description: Creates a mutable ref object that persists across renders. 5 | sidebar_position: 6 6 | --- 7 | 8 | *useRef* is a React hook that allows you to create a mutable value that persists across component renders. It provides a way to store and access a value that **won't trigger a re-render** when it changes. 9 | 10 | Here are a few important things to understand about *useRef*: 11 | 12 | 1. Creating a Ref: 13 | You can create a ref by calling the useRef hook and passing an initial value as an argument: 14 | 15 | ```jsx 16 | const myRef = useRef(initialValue); 17 | ``` 18 | 19 | 2. Mutable Reference: 20 | The value stored in a ref is mutable, meaning you can update it directly without triggering a re-render of the component. 21 | 22 | 3. Preserving Value across Renders: 23 | Unlike regular variables or state values, the value stored in a ref persists across component renders. When the component re-renders, the ref will retain its value from the previous render. 24 | 25 | 4. Accessing the Value: 26 | You can access the current value of a ref using the ```.current``` property. For example: 27 | 28 | ```jsx 29 | console.log(myRef.current); 30 | ``` 31 | 32 | 5. Updating the Value: 33 | 34 | You can update the value stored in a ref using the ```.current``` property. For example: 35 | 36 | ```jsx 37 | myRef.current = newValue; 38 | ``` 39 | 40 | Here's an example to illustrate its usage: 41 | 42 | ```jsx 43 | import React, { useRef } from 'react'; 44 | 45 | const TextInput = () => { 46 | const inputRef = useRef(null); 47 | 48 | const handleClick = () => { 49 | // Accessing the current value 50 | console.log(inputRef.current.value); 51 | 52 | // Updating the value 53 | inputRef.current.value = 'New Value'; 54 | }; 55 | 56 | return ( 57 |
58 | 59 | 60 |
61 | ); 62 | }; 63 | ``` 64 | 65 | In the example above, we create a ref using **useRef** and assign it to inputRef. We then attach this ref to an input element using the ref attribute. This allows us to access the input's value directly through inputRef.current.value. 66 | 67 | In the handleClick function, we log the current value of the input to the console. We can also directly update the value of the input by assigning a new value to inputRef.current.value. 68 | 69 | useRef is particularly useful when you need to interact with DOM elements directly or store mutable values that won't trigger a re-render. It can also be used to store and access any other mutable data throughout the lifecycle of a component. 70 | 71 | Remember that updating the value of a ref using ```.current``` doesn't trigger a re-render. If you want to update the value and cause a re-render, you should use state (useState) instead. 72 | -------------------------------------------------------------------------------- /docs/Hooks/useState.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: react-hook-useState 3 | title: useState 4 | description: Manages state within functional components. 5 | sidebar_position: 2 6 | --- 7 | 8 | The useState hook is a built-in hook provided by React that allows you to add state to functional components. With this hook, you can create and manage state variables within a functional component, giving it the ability to hold and update data. 9 | 10 | The syntax for using useState is as follows: 11 | ```jsx 12 | const [state, setState] = useState(initialValue); 13 | ``` 14 | Let's break down this syntax: 15 | 16 | ```state``` represents the current value of the state variable. 17 | ```setState``` is a function that allows you to update the state variable. 18 | ```initialValue``` is the initial value of the state variable. 19 | Now, let's explore some examples to understand how useState works: 20 | 21 | Example 1: Counter 22 | 23 | ```jsx 24 | import React, { useState } from 'react'; 25 | 26 | const Counter = () => { 27 | const [count, setCount] = useState(0); 28 | 29 | const increment = () => { 30 | setCount(count + 1); 31 | }; 32 | 33 | return ( 34 |
35 |

Count: {count}

36 | 37 |
38 | ); 39 | }; 40 | ``` 41 | In this example, we create a state variable called count and initialize it with 0 using useState(0). The setCount function is used to update the count variable. When the "Increment" button is clicked, the increment function is called, which increments the count by 1. The updated value is then reflected in the component's rendering. 42 | 43 | Example 2: Input Field 44 | 45 | ```jsx 46 | import React, { useState } from 'react'; 47 | 48 | const InputField = () => { 49 | const [text, setText] = useState(''); 50 | 51 | const handleChange = (event) => { 52 | setText(event.target.value); 53 | }; 54 | 55 | return ( 56 |
57 | 58 |

Typed text: {text}

59 |
60 | ); 61 | }; 62 | ``` 63 | In this example, we create a state variable called text and initialize it with an empty string using useState(''). The setText function is used to update the text variable whenever the input field's value changes. The onChange event handler is called, which invokes handleChange and updates the text state with the typed value. The typed text is then displayed below the input field. 64 | 65 | These examples demonstrate how useState enables you to add and manage state in functional components. By using the setState function, you can update the state variable, triggering a re-render of the component and reflecting the updated state in the UI. 66 | 67 | Remember that you can use multiple useState hooks within a single component to manage multiple independent state variables. Each state variable will have its own corresponding setState function. 68 | -------------------------------------------------------------------------------- /docs/Hooks/useTransition.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: react-hook-useTransation 3 | title: useTransation 4 | description: Lets you update the state without blocking the UI. 5 | sidebar_position: 7 6 | --- 7 | 8 | 9 | *useTransition* is a React Hook that lets you update the state without blocking the UI. 10 | 11 | The useTransition hook allows us to specify some state updates as not as important. These state updates will be executed in parallel with other state updates, but the rendering of the component will not wait for these less important state updates. 12 | 13 | ```jsx 14 | function App() { 15 | const [name, setName] = useState("") 16 | const [list, setList] = useState(largeList) 17 | const [isPending, startTransition] = useTransition() 18 | 19 | function handleChange(e) { 20 | setName(e.target.value) 21 | startTransition(() => { 22 | setList(largeList.filter(item => item.name.includes(e.target.value))) 23 | }) 24 | } 25 | 26 | return ( 27 | <> 28 | 29 | {isPending ? ( 30 |
Loading...
31 | ) : ( 32 | list.map(item => ) 33 | )} 34 | 35 | ) 36 | } 37 | ``` 38 | 39 | Calling the *useTransition* hook returns an array with the first value being an *isPending* variable and the second value being the *startTransition* function. The *isPending* variable simply returns true while the code inside the *startTransition* hook is running. Essentially, this variable is true when the slow state update is running and false when it is finished running. The *startTransition* function takes a single callback and this callback just contains all the code related to the slow state update including the setting of the state. 40 | 41 | In our case we are wrapping *setList* in our *startTransition* function which tells React that our *setList* state update is of low importance. This means that as soon as all of our normal state updates are finished that the component should rerender even if this slow state update is not finished. Also, if a user interacts with your application, such as clicking a button or typing in an input, those interactions will take higher priority than the code in the *startTransition* function. This ensures that even if you have really slow code running it won’t block your user from interacting with the application. 42 | 43 | In conclusion, the *useTransition* hook makes working with slow, computationally intense state updates so much easier since now we can tell React to prioritize those updates at a lower level to more important updates which makes your application seem much more performant to users. 44 | 45 | -------------------------------------------------------------------------------- /docs/basics.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: basics 3 | title: Basics 4 | sidebar_position: 2 5 | --- 6 | 7 | # Basics 8 | 9 | React is a JavaScript library for building user interfaces created by Facebook. Using React you can build user interfaces specifically Single Page Applications (SPA) or websites. Let’s learn some basics before jumping into the code. 10 | 11 | - ES6: React uses ES6. It stands for ECMAScript 6. It was created to standardize JavaScript. 12 | - Core syntax: React uses a syntax extension of JavaScript called JSX which allows you to write HTML tag inside javaScript and helps to keep your code readable. For example : 13 | 14 | ```jsx 15 | const element =

Hello World!

16 | ``` 17 | 18 | - Component: Everything in React is a component. Component is an independent, reusable code block. There are two types of components in React. 19 | - 1 Class Component 20 | - 2 Functional Component 21 | 22 | 23 | Let’s see them in detail 24 | 25 | **Class Component**: Class component is an ES6 class. You can create a class component by extending the React-Component. It must have a render( ) method which returns a React element. Let’s create a Class component called Hello : 26 | 27 | 28 | ```jsx 29 | import React from 'react'; 30 | 31 | class Hello extends React.Component { 32 | render() { 33 | return( 34 |

Hello world!

; 35 | ) 36 | } 37 | } 38 | ``` 39 | 40 | Here, the class Hello extends React.Component so React understands that this class is a component. Inside render() it returns a React element. In the example above, it displays h1 tag with the text Hello world! inside it. 41 | 42 | **Functional Component**: It is a JavaScript / ES6 function. It must return a React element. Let’s create a functional component called Hello : 43 | 44 | 45 | ```jsx 46 | function Hello(){ 47 | return( 48 |

Hello world!

; 49 | ) 50 | } 51 | ``` 52 | 53 | or as an ES6 arrow function: 54 | 55 | ```jsx 56 | const Hello = () =>{ 57 | return( 58 |

Hello world!

; 59 | ) 60 | } 61 | ``` 62 | 63 | To get your application render on the screen, we also have to use **ReactDOM.render()** 64 | 65 | ```jsx 66 | ReactDOM.render(,document.getElementById("root")); 67 | ``` 68 | or 69 | 70 | ```jsx 71 | const root = ReactDOM.createRoot(document.getElementById('root')); 72 | root.render(); 73 | ``` 74 | 75 | Here, the above code renders the **Hello** component inside the **DOM** with an id of root. -------------------------------------------------------------------------------- /docs/batching.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: react-batching 3 | title: Batching 4 | sidebar_position: 12 5 | --- 6 | 7 | # Batching ⚙️ 8 | 9 | In ReactJS, batching refers to a process that helps improve the performance of rendering updates to the user interface. It involves grouping multiple state updates or other React operations into a single batch, which is then processed together by React, reducing the number of actual updates performed. 10 | 11 | Batching is particularly useful when you have multiple state updates happening one after another, as it allows React to optimize and minimize the number of times it needs to update the UI. Instead of triggering a re-render for each individual update, React will wait until the end of the batch and then perform a single re-render. 12 | 13 | Here's a simple example to demonstrate batching in ReactJS: 14 | 15 | ```jsx 16 | import React, { useState } from 'react'; 17 | 18 | function Counter() { 19 | const [count, setCount] = useState(0); 20 | 21 | const increment = () => { 22 | setCount(count + 1); 23 | setCount(count + 1); 24 | setCount(count + 1); 25 | }; 26 | 27 | return ( 28 |
29 |

Count: {count}

30 | 31 |
32 | ); 33 | } 34 | 35 | export default Counter; 36 | ``` 37 | 38 | In the above code, we have a Counter component that maintains a count state using the useState hook. Inside the increment function, we update the count state three times in a row. 39 | 40 | Since React batches state updates that occur within the same event handler, instead of performing three separate renders for each setCount call, React will combine them into a single update. As a result, the UI will only re-render once with the final value of count. 41 | 42 | This batching optimization can help prevent unnecessary re-renders and improve the performance of your React application when you have multiple state updates happening closely together. -------------------------------------------------------------------------------- /docs/error-boundary.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: errorboundary 3 | title: ErrorBoundary 4 | sidebar_position: 8 5 | --- 6 | 7 | # React error handling with react-error-boundary ☄️ 8 | 9 | Errors are bound to happen in our applications, whether they’re server-related errors, edge cases, or others. As such, many methods have been developed to prevent these errors from interfering with user and developer experience. In React, one such method is the use of error boundaries. 10 | 11 | ## Error boundaries in React 🟡 12 | Error boundaries were introduced in React 16 as a way to catch and handle JavaScript errors that occur in the UI parts of our component. So error boundaries only catch errors that occur in a lifecycle method, render method, and inside Hooks like useEffect. According to the React documentation, error boundaries do not handle errors in: 13 | - Event handlers 14 | - Asynchronous code (e.g., setTimeout or requestAnimationFrame callbacks) 15 | - Server-side rendering 16 | - Errors thrown in the error boundary itself (rather than its children) 17 | 18 | So basically, error boundaries only handle errors in the parts of our code that involve React. 19 | 20 | To create an error boundary, we simply have to create a class component and define a state variable for determining whether the error boundary has caught an error. Our class component should also have at least three methods: 21 | 22 | - A static method called getDerivedStateFromError, which is used to update the error boundary’s state 23 | - A componentDidCatch lifecycle method for performing operations when our error boundaries catch an error, such as logging to an error logging service 24 | - A render method for rendering our error boundary’s child or the fallback UI in case of an error 25 | 26 | Here’s an example (taken from the React docs) of what our simple error boundary should look like: 27 | 28 | ```jsx 29 | class ErrorBoundary extends React.Component { 30 | constructor(props) { 31 | super(props); 32 | this.state = { hasError: false }; 33 | } 34 | 35 | static getDerivedStateFromError(error) { 36 | // Update state so the next render will show the fallback UI. 37 | return { hasError: true }; 38 | } 39 | 40 | componentDidCatch(error, errorInfo) { 41 | // You can also log the error to an error reporting service 42 | logErrorToMyService(error, errorInfo); 43 | } 44 | 45 | render() { 46 | if (this.state.hasError) { 47 | // You can render any custom fallback UI 48 | return

Something went wrong.

; 49 | } 50 | 51 | return this.props.children; 52 | } 53 | } 54 | ``` 55 | 56 | ## react-error-boundary 🔵 57 | 58 | react-error-boundary is a wrapper around React’s error boundary that allows developers to implement error boundaries in code without building them from scratch. With react-error-boundary, we can simply wrap components where we expect errors with the provided 59 | ErrorBoundary component and pass in some extra props to customize our error boundary’s behavior. 60 | 61 | ## ErrorBoundary component 🔴 62 | 63 | The ErrorBoundary component is the main component available in react-error-boundary. It allows us to implement the typical React error boundary with less code. 64 | 65 | Here’s a very basic use case of ErrorBoundary: 66 | 67 | ```jsx 68 | function App(){ 69 | ... 70 | return ( 71 | 74 | 75 | 76 | ); 77 | } 78 | 79 | const OurFallbackComponent = ({ error, componentStack, resetErrorBoundary }) => { 80 | return ( 81 |
82 |

An error occurred: {error.message}

83 | 84 |
85 | ); 86 | }; 87 | ``` 88 | 89 | In the above component, we simply wrap our component with the ErrorBoundary component and pass in our fallback component to the FallbackComponent prop so that if there’s an error (that can be caught and handled by react-error-boundary), our fallback component will be rendered; otherwise, our component will be rendered. 90 | 91 | We also have the fallbackRender prop, which is a render prop-based API for specifying our fallback component in an inline manner. Here’s the above code block using the fallbackRender prop: 92 | 93 | ```jsx 94 | function App(){ 95 | ... 96 | return ( 97 | ( 99 |
100 |

An error occurred: {error.message}

101 | 102 |
103 | )} 104 | > 105 | 106 |
107 | ); 108 | } 109 | ``` 110 | 111 | The ErrorBoundary also has an onError prop, which acts as a listener that is triggered when our error boundary catches and handles an error in its child components. It is from this place that we might choose to log such errors to whatever error logging service we might be using. 112 | 113 | ```jsx 114 | function App(){ 115 | ... 116 | 117 | return ( 118 | { 120 | logToErrorLoggingService(error, componentStack); 121 | }} 122 | ... 123 | > 124 | 125 | 126 | ); 127 | } 128 | ``` 129 | 130 | - ## ErrorBoundary component ⚫️ 131 | 132 | react-error-boundary also provides a way for our code to recover from errors caught by our error boundaries. This is done using the reset keys and the resetErrorBoundary function passed to the fallback component. 133 | 134 | The best way to explain how this works is to use an example code block taken directly from the React documentation: 135 | 136 | ```jsx 137 | function ErrorFallback({error, componentStack, resetErrorBoundary}) { 138 | return ( 139 |
140 |

Something went wrong:

141 |
{error.message}
142 |
{componentStack}
143 | 144 |
145 | ) 146 | } 147 | 148 | function Bomb() { 149 | throw new Error('💥 KABOOM 💥') 150 | } 151 | 152 | function App() { 153 | const [explode, setExplode] = React.useState(false) 154 | return ( 155 |
156 | 157 | setExplode(false)} 160 | resetKeys={[explode]} 161 | > 162 | {explode ? : null} 163 | 164 |
165 | ) 166 | } 167 | ``` 168 | 169 | As we can see from the code above, a state Hook was created and used to determine whether the App component renders a Bomb component that throws an error or an error-safe component. Reset keys were also passed to the error boundary component. These reset keys determine whether the error boundary’s internal state will be reset. If one of the reset keys change during renders, the error boundary’s internal state will be reset. 170 | 171 | On the other hand, calling the resetComponent function triggers the onResethandler of our ErrorBoundary component, where we set our explode state value to false. This causes our App component to render an error-safe component. 172 | 173 | We also have the onResetKeysChange handler, which is triggered when the value of the reset keys change, causing a reset of the error boundary’s internal state. 174 | 175 | - ## ErrorBoundary component 🟢 176 | 177 | react-error-boundary enables React developers to reduce the amount of code that must be written and expand their error boundary capabilities to catch other forms of errors that wouldn’t otherwise be identified by regular error boundaries. Learn more about react-error-boundary on GitHub. 178 | -------------------------------------------------------------------------------- /docs/immutability.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: Immutability 3 | title: Immutability 4 | sidebar_position: 6 5 | --- 6 | 7 | # Immutability in React 📌 8 | 9 | One of the first things you learn when you begin working with React is that you shouldn’t mutate or modify a list: 10 | 11 | ```jsx 12 | // This is bad, push modifies the original array 13 | items.push(newItem); 14 | // This is good, concat doesn’t modify the original array 15 | const newItems = items.concat([newItem]); 16 | ``` 17 | 18 | Despite popular belief, there’s actually nothing wrong with mutating objects. In certain situations, like concurrency, it can become a problem, however, mutating objects is the easiest development approach. Just like most things in programming, it’s a trade-off. 19 | 20 | Functional programming and concepts like immutability are popular topics. But in the case of React, immutability isn’t just fashionable, it has some real benefits. In this article, we’ll explore immutability in React, covering what it is and how it works. Let’s get started! 21 | 22 | ## What is immutability? 🟠 23 | 24 | If something is immutable, we cannot change its value or state. Although this may seem like a simple concept, as usual, the devil is in the details. 25 | 26 | You can find immutable types in JavaScript itself; the String value type is a good example. If you define a string as follows, you cannot change a character of the string directly: 27 | 28 | ```jsx 29 | var str = 'abc'; 30 | ``` 31 | 32 | In JavaScript, strings are not arrays, so you can define one as follows: 33 | 34 | ```jsx 35 | str[2] = 'd'; 36 | ``` 37 | 38 | Defining a string using the method below assigns a different string to str: 39 | 40 | ```javascript 41 | str = 'abd'; 42 | ``` 43 | 44 | You can even define the str reference as a constant: 45 | 46 | ```javascript 47 | const str = 'abc' 48 | ``` 49 | 50 | Therefore, assigning a new string generates an error. However, this doesn’t relate to immutability. If you want to modify the string value, you have to use manipulation methods like replace(), toUpperCase(), or trim(). All of these methods return new strings; they don’t modify the original one. 51 | 52 | ## Value type 🟣 53 | 54 | It’s important to pay attention to the value type. String values are immutable, but string objects are not. 55 | 56 | ```javascript 57 | const str = new String("abc"); 58 | str.myNewProperty = "some value"; 59 | 60 | alert(str.myNewProperty); 61 | 62 | str.myNewProperty = "a new value"; 63 | 64 | alert(str.myNewProperty); 65 | ``` 66 | 67 | Strings are immutable. The last example creates an object with the String() constructor that wraps the immutable string value. You can add new properties to this wrapper because it’s an object, and it’s not frozen. This example leads us to a concept that is important to understand; the difference between reference and value equality. 68 | 69 | 70 | ## Reference equality vs value equality 71 | 72 | With reference equality, you compare object references with either the === and !== operators or the == and != operators. If the references point to the same object, they are considered equal: 73 | 74 | ```javascript 75 | var str1 = ‘abc’; 76 | var str2 = str1; 77 | str1 === str2 // true 78 | ``` 79 | 80 | In the example above, both the str1 and str2references are equal because they point to the same object, 'abc': 81 | 82 | ![immutability pic](https://user-images.githubusercontent.com/96326525/213646878-b040cbac-f16c-4b26-80d2-a11cbb55fedd.png) 83 | 84 | Two references are also equal when they refer to the same value if this value is immutable: 85 | 86 | ```javascript 87 | var str1 = ‘abc’; 88 | var str2 = ‘abc’; 89 | str1 === str2 // true 90 | var n1 = 1; 91 | var n2 = 1; 92 | n1 === n2 // also true 93 | ``` 94 | 95 | ![immutability pic](https://user-images.githubusercontent.com/96326525/213647083-594db53c-73a2-408b-924e-17d74f57c53d.png) 96 | 97 | But, when talking about objects, this doesn’t hold true anymore: 98 | 99 | ```javascript 100 | var str1 = new String(‘abc’); 101 | var str2 = new String(‘abc’); 102 | str1 === str2 // false 103 | var arr1 = []; 104 | var arr2 = []; 105 | arr1 === arr2 // false 106 | ``` 107 | 108 | In each of these cases, two different objects are created, and therefore, their references are not equal: 109 | ![immutability pic](https://user-images.githubusercontent.com/96326525/213648117-2408c701-b7ae-4fd0-adbd-1cea64806c8e.png) 110 | 111 | If you want to check if two objects contain the same value, you have to use value equality, where you compare the values of the properties of the object. 112 | 113 | In JavaScript, there’s no direct way to perform value equality on objects and arrays. If you’re working with string objects, you can use the valueOf or trim methods, which return a string value: 114 | 115 | ```javascript 116 | var str1 = new String(‘abc’); 117 | var str2 = new String(‘abc’); 118 | str1.valueOf() === str2.valueOf() // true 119 | str1.trim() === str2.trim() // true 120 | ``` 121 | 122 | For any other type of object, you either have to implement your own equals method or use a third-party library. It’s easier to test if two objects are equal if they are immutable. React takes advantage of this concept to make some performance optimizations; let’s explore these in detail. 123 | 124 | ## Immutability performance optimizations in React 🔵 125 | 126 | React maintains an internal representation of the UI, called the virtual DOM. When either a property or the state of a component changes, the virtual DOM is updated to reflect those changes. Manipulating the virtual DOM is easier and faster because nothing is changed in the UI. Then, React compares the virtual DOM with the version before the update to know what changed, known as the reconciliation process. 127 | 128 | Therefore, only the elements that changed are updated in the real DOM. However, sometimes, parts of the DOM are re-rendered even when they didn’t change. In this case, they’re a side effect of other parts that do change. You could implement the shouldComponentUpdate() function to check if the properties or the state really changed, then return true to let React perform the update: 129 | 130 | ```jsx 131 | class MyComponent extends Component { 132 | // ... 133 | shouldComponentUpdate(nextProps, nextState) { 134 | if (this.props.myProp !== nextProps.color) { 135 | return true; 136 | } 137 | return false; 138 | } 139 | // ... 140 | } 141 | ``` 142 | 143 | If the properties and state of the component are immutable objects or values, you can check to see if they changed with a simple equality operator. 144 | 145 | From this perspective, immutability removes complexity because sometimes it is hard to know exactly what changed. For example, think about deep fields: 146 | 147 | ```javascript 148 | myPackage.sender.address.country.id = 1; 149 | ``` 150 | 151 | How can you efficiently track which nested object changed? Think about arrays. For two arrays of the same size, the only way to know if they are equal is by comparing each element, which is a costly operation for large arrays. 152 | 153 | The most simple solution is to use immutable objects. If the object needs to be updated, you have to create a new object with the new value since the original one is immutable and cannot be changed. You can use reference equality to know that it changed. 154 | 155 | The React documentation also suggests treating state as if it were immutable. Directly manipulating the state nullifies React’s state management, resulting in performance issues. The React useState Hook plays a vital role in performance optimization, allowing you to avoid directly manipulating the state in functional components. 156 | 157 | To some people, this concept may seem a little inconsistent or opposed to the ideas of performance and simplicity. So, let’s review the options you have to create new objects and implement immutability. 158 | 159 | ## Implementing immutability in React 🟠 160 | 161 | In most real world applications, your state and properties will be objects and arrays. JavaScript provides some methods to create new versions of them. 162 | 163 | ### Object.assign 164 | 165 | Instead of manually creating an object with the new property, you can use Object.assign to avoid defining the unmodified properties: 166 | 167 | ```javascript 168 | const modifyShirt = (shirt, newColor, newSize) => { 169 | return { 170 | id: shirt.id, 171 | desc: shirt.desc, 172 | color: newColor, 173 | size: newSize 174 | }; 175 | } 176 | 177 | 178 | const modifyShirt = (shirt, newColor, newSize) => { 179 | return Object.assign( {}, shirt, { 180 | color: newColor, 181 | size: newSize 182 | }); 183 | } 184 | ``` 185 | 186 | Object.assign will copy all of the properties of the objects passed as parameters, starting from the second parameter to the object specified in the first parameter. 187 | 188 | ### Spread operator 189 | 190 | You can use the spread operator with the same effect; the difference is that Object.assign() uses setter methods to assign new values, while the spread operator doesn’t: 191 | 192 | ```javascript 193 | const modifyShirt = (shirt, newColor, newSize) => { 194 | return { 195 | ...shirt, 196 | color: newColor, 197 | size: newSize 198 | }; 199 | } 200 | ``` 201 | 202 | You can also use the spread operator to create arrays with new values: 203 | 204 | ```javascript 205 | const addValue = (arr) => { 206 | return [...arr, 1]; 207 | }; 208 | ``` 209 | 210 | ### Concat and Slice methods 211 | 212 | Alternately, you can use methods like concat or slice, which return a new array without modifying the original one: 213 | 214 | ```javascript 215 | const addValue = (arr) => { 216 | return arr.concat([1]); 217 | }; 218 | const removeValue = (arr, index) => { 219 | return arr.slice(0, index) 220 | .concat( 221 | arr.slice(index+1) 222 | ); 223 | }; 224 | ``` 225 | 226 | In this gist, you’ll see how to combine the spread operator with these methods to avoid mutating arrays while performing common operations. 227 | 228 | However, there are two main drawbacks to using these native approaches. For one, they copy properties or elements from one object or array to another, which could be a slow operation for larger objects and arrays. In addition, objects and arrays are mutable by default. There’s nothing that enforces immutability. You have to remember to use one of these methods. 229 | 230 | For these reasons, it’s better to use an external library that handles immutability. 231 | 232 | ## Immutability libraries 🟣 233 | The React team recommends Immutable.js and immutability-helper, but you can find many libraries with similar functionality. There are three main types: 234 | - Libraries that work with specialized data structures 235 | - Libraries that work by freezing objects 236 | - Libraries with helper functions that perform immutable operations 237 | Most of these libraries work with persistent data structures. 238 | 239 | ## Benefits of immutability 🔵 240 | Overall, immutability improves your app’s performance and promotes easy debugging. It allows for the simple and inexpensive implementation of sophisticated techniques for detecting changes, and it ensures that the computationally expensive process of updating the DOM is performed only when absolutely necessary. 241 | 242 | ## Disadvantages of immutability 🟢 243 | 244 | However, immutability is not without its own problems. As I mentioned before, when working with objects and arrays, you either have to remember to use methods than enforce immutability or use third-party libraries. 245 | 246 | Many of these libraries work with their own data types. Although they provide compatible APIs and ways to convert these types to native JavaScript types, you have to be careful when designing your application to avoid high degrees of coupling or harm performance with methods like toJs(). 247 | 248 | If the library doesn’t implement new data structures, for example, libraries that work by freezing objects, there won’t be any of the benefits of structural sharing. Most likely, objects will be copied when updated, and performance will suffer in some cases. 249 | 250 | Additionally, implementing immutability concepts with larger teams can be time-consuming because individual developers must be disciplined, especially when using third-party libraries with steep learning curves. You also have to consider the learning curve associated with these libraries. 251 | 252 | 253 | ## Conclusion 🟠 254 | Understanding immutability is essential for React developers. An immutable value or object cannot be changed, so every update creates new value, leaving the old one untouched. For example, if your application state is immutable, you can save all the state objects in a single store to easily implement functionality to undo and redo. 255 | 256 | Version control systems like Git work in a similar way. Redux is also based on that principle. However, the focus on Redux is more on the side of pure functions and snapshots of the application state. 257 | 258 | Immutability has other advantages like avoiding unexpected side effects or reducing coupling, but it also has disadvantages. Remember, as with many things in programming, it’s a trade-off. 259 | -------------------------------------------------------------------------------- /docs/introduction.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: introduction 3 | title: Introduction 4 | sidebar_position: 1 5 | --- 6 | 7 | # Introduction 8 | 9 | Welcome to my ReactJS notebook repository! This repository is a collection of notes and examples on learning ReactJS. It covers the basics of the library and progresses to more advanced topics. The goal of this repository is to provide a useful resource for anyone looking to learn ReactJS, as well as a personal notebook for tracking my own progress📊. If you find this repository helpful, please consider giving it a star to show your support. Thank you! 10 | 11 | You can use this repository as a starting point and edit it to fit your needs. -------------------------------------------------------------------------------- /docs/proptypes.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: proptypes 3 | title: PropTypes 4 | sidebar_position: 7 5 | --- 6 | 7 | # PropTypes in React 📊 8 | 9 | PropTypes are a good first line defense when it comes to debugging your apps. But before getting into detail about PropTypes, we have to understand the concept of props. 10 | 11 | 12 | Props are the read-only properties that are shared between components to give the unidirectional flow of React a dynamic touch. They're mainly shared from the parent component to the child component, but the reverse is also possible (though not recommended). 13 | 14 | ## What are PropTypes? 🟢 15 | PropTypes are simply a mechanism that ensures that the passed value is of the correct datatype. This makes sure that we don’t receive an error at the very end of our app by the console which might not be easy to deal with. 16 | 17 | I don't recommend using them in short apps like projects for self-practice but it's totally up to you. For larger projects like for a client, it's often a wise choice and a good practice to use them. 18 | 19 | There are many different types of PropTypes and all of them have their unique ES6 classes which we can use. We will discuss every type in this article. 20 | 21 | ## How to use PropTypes? 🟣 22 | Before the release of React 15.5.0, PropTypes were available in the React package, but now we have to add the prop-types library in our project. 23 | 24 | We can do so by running the following command in our terminal: 25 | 26 | ```javascript 27 | npm install prop-types --save 28 | ``` 29 | 30 | We can use PropTypes to validate any data we are receiving from props. But before using it we will have to import it as always in our app: 31 | 32 | ```jsx 33 | import PropTypes from 'prop-types'; 34 | ``` 35 | They are often used after the component ends and starts with the name of the component as shown: 36 | 37 | ```jsx 38 | import React from 'react'; 39 | import { PropTypes } from "prop-types"; 40 | 41 | const Count = (props) => { 42 | return ( 43 | <> 44 | ......... 45 | 46 | ) 47 | }; 48 | 49 | Count.propTypes = { 50 | // key is the name of the prop and 51 | // value is the PropType 52 | } 53 | export default Count; 54 | ``` 55 | 56 | PropTypes are also objects with a key and a value pair where the ‘key’ is the name of the prop while the value represents the type or class by which they are defined. 57 | 58 | Since defining PropTypes on a component does not depend on the component implementation, we will be leaving out the code for the component itself in all the following examples. The code above can be simplified to the following: 59 | 60 | 61 | ```jsx 62 | Count.propTypes = { 63 | // Put props here 64 | } 65 | ``` 66 | 67 | Let's discuss how many types of PropTypes are there before understanding them with an example. 68 | 69 | ## Basic Types of PropTypes 🔵 70 | 71 | 72 | The most basic way we can check a prop's type is by checking if it falls under the category of primitive types in JavaScript, such as a boolean, string, object, and so on. 73 | 74 | Below is the list of all data types that are considered primitive or the basic ones with their classes that we can use to check props. 75 | ![propTypes pic](https://user-images.githubusercontent.com/96326525/214465188-748d52a4-339b-4fd2-8781-d368c35b99d7.png) 76 | 77 | Below is an example that shows us how to use these PropTypes for type checking in our app. As we discussed already, they are defined as objects with a key and a value pair where the key is the name of the object while value contains the classes which will be used for type checking. 78 | 79 | ```jsx 80 | Count.propTypes = { 81 | name: PropTypes.string, 82 | age: PropTypes.number, 83 | address: PropTypes.object, 84 | friends: PropTypes.array, 85 | }; 86 | ``` 87 | 88 | In the above code, the name prop is expected to have a value which is a string, age is a number, address is an object, and friends is an array. If any value other than this has been used for the same props as a value, it will show an error in the console like this: 89 | ![propTypes](https://user-images.githubusercontent.com/96326525/214465416-b4124b82-97d9-4095-941b-f808352a442e.png) 90 | 91 | We can chain any of the above with isRequired to make sure a warning is shown if the prop isn't provided. 92 | 93 | ```jsx 94 | Count.propTypes = { 95 | basicObject: PropTypes.object, 96 | numbers: PropTypes.objectOf(PropTypes.numbers), 97 | messages: PropTypes.instanceOf(Message), 98 | contactList: PropTypes.shape({ 99 | name: PropTypes.string.isRequired, 100 | phone: PropTypes.string.isRequired, 101 | }), 102 | }; 103 | ``` 104 | 105 | ## Conclusion 🟢 106 | 107 | PropTypes are a great way to catch errors at run time and act as the first line of defense for your applications. They're not as type-safe as TypeScript but they're much easier to set up and work with. -------------------------------------------------------------------------------- /docs/react-children.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: react-children 3 | title: Children 4 | sidebar_position: 10 5 | --- 6 | 7 | # Children Props 👻 8 | 9 | The most obvious and common prop that developers work with within React is the children prop. In the majority of cases, there is no need to understand how the children prop looks like. But in some cases, we want to inspect the children prop to maybe wrap each child in another element/component or to reorder or slice them. In those cases inspecting how the children prop looks like becomes essential. 10 | 11 | You can use props.children in React in order to access and utilize what you put inside the open and closing tags when you are creating an instance of a component. 12 | 13 | For example, if I have a Button component, I can create an instance of it like this: ``` 19 | } 20 | ``` 21 | 22 | I can then instantiate the component with `````` and then a button with the text click me would display on the page. 23 | 24 | For a layout, I could do something like: 25 | 26 | ```jsx 27 | function Container ({ children }) { 28 | return
{children}
29 | } 30 | ``` 31 | 32 | Note: in this example, I'm destructuring the props object, so I can use children directly. 33 | 34 | And then to instantiate it I could do: 35 | 36 | ```jsx 37 | 38 |

Welcome to my App

39 |

Hello, hi, this is my paragraph

40 |
41 | ``` 42 | 43 | Normally in order to pass props from one component to another, you need to do ```; 35 | }; 36 | export default ActionButton; 37 | ``` 38 | 39 | The ``` 51 | ); 52 | }; 53 | export default ActionButton; 54 | ``` 55 | 56 | This way, at any time in the lifecycle of the component, we can access the actual HTML element at buttonRef.current. 57 | 58 | Now we know how to access DOM nodes inside a React component. Let’s take a look at some of the situations where this may be useful. 59 | 60 | ## Using React refs 🟣 61 | 62 | One of the many concepts that React popularized among developers is the concept of declarative views. Before declarative views, most of us were modifying the DOM by calling functions that explicitly changed it. 63 | 64 | As mentioned at the introduction of this article, we are now declaring views based on a state, and — though we are still calling functions to alter this state — we are not in control of when the DOM will change or even if it should change. 65 | 66 | Because of this inversion of control, we’d lose this imperative nature if it weren’t for refs. 67 | Here are a few use cases where it may make sense to bring refs into your code. 68 | 69 | ## Focus control 🟡 70 | 71 | You can achieve focus in an element programmatically by calling focus() on the node instance. 72 | Because the DOM exposes this as a function call, the best way to do this in React is to create a ref and manually do it when we think it’s suitable. 73 | 74 | ```jsx 75 | import React, { useState } from "react"; 76 | const InputModal = ({ initialValue, onSubmit, onClose }) => { 77 | const [value, setValue] = useState(initialValue); 78 | const onChange = (e) => { 79 | setValue(e.target.value); 80 | }; 81 | const onSubmit = (e) => { 82 | e.preventDefault(); 83 | onSubmit(value); 84 | onClose(); 85 | }; 86 | return ( 87 |
88 |
89 |

Insert a new value

90 |
91 | 92 | 93 |
94 |
95 |
96 | ); 97 | }; 98 | export default InputModal; 99 | ``` 100 | In this modal, we allow the user to modify a value already set in the screen below. It would be a better user experience if the input was on focus when the modal opens, which could enable a smooth keyboard transition between the two screens. 101 | 102 | The first thing we need to do is get a reference for the input: 103 | 104 | ```jsx 105 | import React, { useRef, useState } from "react"; 106 | const InputModal = ({ initialValue, onSubmit, onClose }) => { 107 | const [value, setValue] = useState(initialValue); 108 | const inputRef = useRef(null); 109 | const onChange = (e) => { 110 | setValue(e.target.value); 111 | }; 112 | const onSubmit = (e) => { 113 | e.preventDefault(); 114 | onSubmit(value); 115 | onClose(); 116 | }; 117 | return ( 118 |
119 |
120 |

Insert a new value

121 |
122 | 126 | 127 |
128 |
129 |
130 | ); 131 | }; 132 | export default InputModal; 133 | ``` 134 | 135 | Next, when our modal mounts, we imperatively call focus on our input ref within a useEffect: 136 | 137 | ```jsx 138 | import React, { useEffect, useRef, useState } from "react"; 139 | const InputModal = ({ initialValue, onSubmit, onClose }) => { 140 | const [value, setValue] = useState(initialValue); 141 | const inputRef = useRef(null); 142 | useEffect(() => { 143 | inputRef.current.focus(); 144 | }, []) 145 | const onChange = (e) => { 146 | setValue(e.target.value); 147 | }; 148 | const onSubmit = (e) => { 149 | e.preventDefault(); 150 | onSubmit(value); 151 | onClose(); 152 | }; 153 | return ( 154 |
155 |
156 |

Insert a new value

157 |
158 | 162 | 163 |
164 |
165 |
166 | ); 167 | }; 168 | export default InputModal; 169 | ``` 170 | 171 | So when you open the modal, you should see the text box focused by default: 172 | ![refs pic](https://user-images.githubusercontent.com/96326525/216524586-defd12f8-0da7-44ca-9a34-4e6e3849856a.png) 173 | 174 | Remember that you need to access the element through the current property. 175 | 176 | ## Conclusion 🔵 177 | 178 | We started with a recap on the basic concepts of React and its usage, why we generally shouldn’t break the framework’s model, and why we may sometimes need to. 179 | 180 | Accessing the DOM through the interface the library exposes helps to maintain the internals of React in place (remember that useState contains more logic than just triggering a re-render cycle, like batching updates and, in the future, time slicing). 181 | 182 | Remember to use refs only when there is an implicit function call that React can’t handle through its methods. Also, make sure it doesn’t alter the internal state of the components. For more information, read the official React documentation about refs. -------------------------------------------------------------------------------- /docs/react-terms.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: Terms 3 | title: Terms 4 | sidebar_position: 5 5 | --- 6 | 7 | # React Terms 8 | 9 | - ## Single-page Application [SPA] 🟠 10 | 11 | A single-page application is an application that loads a single HTML page and all the necessary assets (such as JavaScript and CSS) required for the application to run. Any interactions with the page or subsequent pages do not require a round trip to the server which means the page is not reloaded. 12 | 13 | Though you may build a single-page application in React, it is not a requirement. React can also be used for enhancing small parts of existing websites with additional interactivity. Code written in React can coexist peacefully with markup rendered on the server by something like PHP, or with other client-side libraries. In fact, this is exactly how React is being used at Facebook. 14 | 15 | - ## ES6, ES2015, ES2016, etc 🔴 16 | 17 | These acronyms all refer to the most recent versions of the ECMAScript Language Specification standard, which the JavaScript language is an implementation of. The ES6 version (also known as ES2015) includes many additions to the previous versions such as: arrow functions, classes, template literals, let and const statements. You can learn more about specific versions here. 18 | 19 | - ## Compilers 🟤 20 | 21 | A JavaScript compiler takes JavaScript code, transforms it and returns JavaScript code in a different format. The most common use case is to take ES6 syntax and transform it into syntax that older browsers are capable of interpreting. Babel is the compiler most commonly used with React. 22 | 23 | - ## Bundlers 🟡 24 | 25 | Bundlers take JavaScript and CSS code written as separate modules (often hundreds of them), and combine them together into a few files better optimized for the browsers. Some bundlers commonly used in React applications include Webpack and Browserify. 26 | 27 | - ## Package Managers 🟢 28 | 29 | Package managers are tools that allow you to manage dependencies in your project.npm and Yarn are two package managers commonly used in React applications. Both of them are clients for the same npm package registry. 30 | 31 | - ## CDN 🔵 32 | 33 | CDN stands for Content Delivery Network. CDNs deliver cached, static content from a network of servers across the globe. 34 | 35 | - ## JSX 🟡 36 | 37 | JSX is a syntax extension to JavaScript. It is similar to a template language, but it has full power of JavaScript. JSX gets compiled to React.createElement() calls which return plain JavaScript objects called “React elements”. To get a basic introduction to JSX see the docs here and find a more in-depth tutorial on JSX here. 38 | 39 | React DOM uses camelCase property naming convention instead of HTML attribute names. For example, tabindex becomes tabIndex in JSX. The attribute class is also written as className since class is a reserved word in JavaScript: 40 | ```html 41 |

My name is Mutasim!

42 | ``` 43 | 44 | - ## Elements 🟠 45 | 46 | React elements are the building blocks of React applications. One might confuse elements with a more widely known concept of “components”. An element describes what you want to see on the screen. React elements are immutable. 47 | ```javascript 48 | const element =

Hello, world

; 49 | ``` 50 | Typically, elements are not used directly, but get returned from components. 51 | 52 | - ## Components 🔴 53 | 54 | React components are small, reusable pieces of code that return a React element to be rendered to the page. The simplest version of React component is a plain JavaScript function that returns a React element: 55 | ```javascript 56 | function Welcome(props) { 57 | return

Hello, {props.name}

; 58 | } 59 | ``` 60 | Components can also be ES6 classes: 61 | ```javascript 62 | class Welcome extends React.Component { 63 | render() { 64 | return

Hello, {this.props.name}

; 65 | } 66 | } 67 | ``` 68 | Components can be broken down into distinct pieces of functionality and used within other components. Components can return other components, arrays, strings and numbers. A good rule of thumb is that if a part of your UI is used several times (Button, Panel, Avatar), or is complex enough on its own (App, FeedStory, Comment), it is a good candidate to be a reusable component. Component names should also always start with a capital letter (`````` not ``````). 69 | 70 | - ## props 🟤 71 | 72 | props are inputs to a React component. They are data passed down from a parent component to a child component. 73 | 74 | Remember that props are readonly. They should not be modified in any way: 75 | 76 | ```javascript 77 | // Wrong! 78 | props.number = 42; 79 | ``` 80 | If you need to modify some value in response to user input or a network response, use state instead. 81 | 82 | - ## props.children 🔵 83 | 84 | props.children is available on every component. It contains the content between the opening and closing tags of a component. For example: 85 | 86 | ```html 87 | Hello world! 88 | ```` 89 | 90 | The string Hello world! is available in props.children in the Welcome component: 91 | 92 | ```javascript 93 | function Welcome(props) { 94 | return

{props.children}

; 95 | } 96 | ``` 97 | 98 | For components defined as classes, use this.props.children: 99 | 100 | ```javascript 101 | class Welcome extends React.Component { 102 | render() { 103 | return

{this.props.children}

; 104 | } 105 | } 106 | ``` 107 | 108 | - ## state 🟡 109 | 110 | A component needs state when some data associated with it changes over time. For example, a Checkbox component might need isChecked in its state, and a NewsFeed component might want to keep track of fetchedPosts in its state. 111 | 112 | The most important difference between state and props is that props are passed from a parent component, but state is managed by the component itself. A component cannot change its props, but it can change its state. 113 | 114 | For each particular piece of changing data, there should be just one component that “owns” it in its state. Don’t try to synchronize states of two different components. Instead, lift it up to their closest shared ancestor, and pass it down as props to both of them. 115 | 116 | 117 | - ## Lifecycle Methods 🔵 118 | 119 | Lifecycle methods are custom functionality that gets executed during the different phases of a component. There are methods available when the component gets created and inserted into the DOM (mounting), when the component updates, and when the component gets unmounted or removed from the DOM. 120 | 121 | - ## Controlled vs. Uncontrolled Components 🔴 122 | 123 | React has two different approaches to dealing with form inputs. 124 | 125 | An input form element whose value is controlled by React is called a controlled component. When a user enters data into a controlled component a change event handler is triggered and your code decides whether the input is valid (by re-rendering with the updated value). If you do not re-render then the form element will remain unchanged. 126 | 127 | An uncontrolled component works like form elements do outside of React. When a user inputs data into a form field (an input box, dropdown, etc) the updated information is reflected without React needing to do anything. However, this also means that you can’t force the field to have a certain value. 128 | 129 | In most cases you should use controlled components. 130 | 131 | - ## Keys 🟠 132 | 133 | A “key” is a special string attribute you need to include when creating arrays of elements. Keys help React identify which items have changed, are added, or are removed. Keys should be given to the elements inside an array to give the elements a stable identity. 134 | 135 | Keys only need to be unique among sibling elements in the same array. They don’t need to be unique across the whole application or even a single component. 136 | 137 | Don’t pass something like Math.random() to keys. It is important that keys have a “stable identity” across re-renders so that React can determine when items are added, removed, or re-ordered. Ideally, keys should correspond to unique and stable identifiers coming from your data, such as post.id. 138 | 139 | - ## Refs 🔵 140 | 141 | React supports a special attribute that you can attach to any component. The ref attribute can be an object created by React.createRef() function or a callback function, or a string (in legacy API). When the ref attribute is a callback function, the function receives the underlying DOM element or class instance (depending on the type of element) as its argument. This allows you to have direct access to the DOM element or component instance. 142 | 143 | Use refs sparingly. If you find yourself often using refs to “make things happen” in your app, consider getting more familiar with top-down data flow. 144 | 145 | 146 | - ## Events 🟢 147 | 148 | Handling events with React elements has some syntactic differences: 149 | 150 | - React event handlers are named using camelCase, rather than lowercase. 151 | - With JSX you pass a function as the event handler, rather than a string. 152 | 153 | - ## Reconciliation 🔴 154 | 155 | When a component’s props or state change, React decides whether an actual DOM update is necessary by comparing the newly returned element with the previously rendered one. When they are not equal, React will update the DOM. This process is called “reconciliation”. -------------------------------------------------------------------------------- /docs/reconciliation.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: reconciliation 3 | title: Reconciliation 4 | sidebar_position: 15 5 | --- 6 | # Reconciliation 💎 7 | 8 | As a developer who has spent countless hours working with React, I have always been fascinated by the inner workings of this powerful library. React's ability to efficiently update the user interface, thanks to its reconciliation algorithm, has been a topic of great intrigue for me. In this blog post, I want to take you on a journey through my experience with React's reconciliation algorithm, exploring how it works and why it's so crucial for building performant web applications. 9 | 10 | ## The Birth of a Virtual DOM ⚙️ 11 | 12 | My journey into the world of React's reconciliation began with the realization that traditional DOM manipulation could be slow and inefficient, especially when dealing with complex user interfaces. React introduced a novel concept—the Virtual DOM. Instead of directly manipulating the actual DOM, React creates a virtual representation of it. This virtual representation allows React to perform comparisons and updates much more efficiently. 13 | 14 | ## The Basics of Reconciliation 🛠️ 15 | 16 | Reconciliation is React's process of updating the actual DOM to match changes in the virtual representation. It's a critical part of what makes React so fast and efficient. When you make changes to your application's state, React doesn't immediately update the DOM. Instead, it follows a series of steps to determine the most efficient way to update the DOM while minimizing performance bottlenecks. 17 | 18 | ## The Diffing Algorithm 💡 19 | 20 | At the heart of React's reconciliation process lies the _diffing algorithm_. This algorithm efficiently computes the difference between the current virtual DOM and the new virtual DOM, resulting from a state or prop change. It identifies which parts of the virtual DOM have changed and updates only those parts in the actual DOM. This selective updating is what makes React so performant. 21 | 22 | ![Image](https://miro.medium.com/v2/resize:fit:638/0*fFLhD2DrRCW3S2NB.) 23 | 24 | 25 | ## Key Concepts in Reconciliation ✨ 26 | 27 | ### 1. Element Reuse 28 | 29 | One key concept in React's reconciliation is the reuse of elements whenever possible. Rather than recreating elements from scratch, React attempts to update existing elements with new data. This approach saves both memory and processing power. 30 | 31 | ### 2. Keys 32 | 33 | Keys are a crucial part of reconciliation. They help React identify which elements have changed, moved, or been added or removed. Properly using keys can significantly improve the performance of your React applications. 34 | 35 | ### 3. Component Lifecycle Methods 36 | 37 | Understanding when and how React components update is also essential for grasping the reconciliation process fully. Component lifecycle methods, such as `componentDidUpdate`, provide hooks to interact with the reconciliation process. 38 | 39 | ## The Art of Optimization 40 | 41 | As I delved deeper into React's reconciliation algorithm, I began to appreciate the art of optimization. There are various ways to optimize your React application further, like shouldComponentUpdate and React's built-in PureComponent. These techniques can help you fine-tune your components' rendering and improve performance significantly. 42 | 43 | ## Conclusion 44 | 45 | My journey through React's reconciliation algorithm has been both enlightening and rewarding. Understanding how React efficiently updates the DOM through its virtual representation has allowed me to build faster, more responsive web applications. As a developer, it's essential to go beyond the surface and grasp the inner workings of the tools we use. React's reconciliation algorithm is undoubtedly one of the jewels in its crown, and I encourage every React developer to explore it further. 46 | 47 | In conclusion, React's reconciliation algorithm is not just a technical detail but a fundamental concept that empowers us to create blazing-fast web applications. It's a testament to the innovation and craftsmanship that go into building developer tools that make our lives easier and our applications better. So, the next time you're working with React, take a moment to appreciate the magic happening behind the scenes—the magic of reconciliation. 48 | -------------------------------------------------------------------------------- /docusaurus.config.js: -------------------------------------------------------------------------------- 1 | const lightCodeTheme = require('prism-react-renderer/themes/github'); 2 | const darkCodeTheme = require('prism-react-renderer/themes/dracula'); 3 | 4 | /** @type {import('@docusaurus/types').Config} */ 5 | const config = { 6 | title: 'ReactJS Notebook 📔', 7 | tagline: `If you are not taking notes, you are not learning!`, 8 | favicon: 'img/logo.png', 9 | 10 | url: 'https://your-docusaurus-test-site.com', 11 | baseUrl: '/', 12 | organizationName: 'mutasim77', 13 | projectName: 'ReactJS-Notebook', 14 | 15 | onBrokenLinks: 'throw', 16 | onBrokenMarkdownLinks: 'warn', 17 | i18n: { 18 | defaultLocale: 'en', 19 | locales: ['en'], 20 | }, 21 | 22 | presets: [ 23 | [ 24 | 'classic', 25 | /** @type {import('@docusaurus/preset-classic').Options} */ 26 | ({ 27 | docs: { 28 | sidebarPath: require.resolve('./sidebars.js'), 29 | }, 30 | blog: { 31 | showReadingTime: true, 32 | }, 33 | theme: { 34 | customCss: require.resolve('./src/css/custom.css'), 35 | }, 36 | }), 37 | ], 38 | ], 39 | 40 | themeConfig: 41 | /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ 42 | ({ 43 | image: 'img/docusaurus-social-card.jpg', 44 | navbar: { 45 | title: 'ReactJs', 46 | logo: { 47 | alt: 'Notebook Logo', 48 | src: 'img/logo.png', 49 | }, 50 | 51 | items: [ 52 | { 53 | type: 'docSidebar', 54 | sidebarId: 'tutorialSidebar', 55 | position: 'left', 56 | label: 'Notes', 57 | }, 58 | { to: '/blog', label: 'Blog', position: 'left' }, 59 | { 60 | href: 'https://github.com/mutasim77/ReactJS-Notebook', 61 | label: 'GitHub', 62 | position: 'right', 63 | }, 64 | ], 65 | }, 66 | 67 | footer: { 68 | style: 'dark', 69 | links: [ 70 | { 71 | title: 'Docs', 72 | items: [ 73 | { 74 | label: 'Notes', 75 | to: '/docs/introduction', 76 | }, 77 | { 78 | label: 'Hooks', 79 | to: '/docs/Hooks/react-hooks', 80 | }, 81 | ], 82 | }, 83 | { 84 | title: 'Community', 85 | items: [ 86 | { 87 | label: 'Discord', 88 | href: 'https://discordapp.com/users/mvtasim', 89 | }, 90 | { 91 | label: 'Twitter', 92 | href: 'https://twitter.com/mvtasim77', 93 | }, 94 | ], 95 | }, 96 | { 97 | title: 'More', 98 | items: [ 99 | { 100 | label: 'Blog', 101 | href: '/blog' 102 | }, 103 | { 104 | label: 'GitHub', 105 | href: 'https://github.com/mutasim77/ReactJS-Notebook', 106 | }, 107 | ], 108 | }, 109 | ], 110 | copyright: `Copyright © 2022 - ${new Date().getFullYear()} Mutasim`, 111 | }, 112 | prism: { 113 | theme: lightCodeTheme, 114 | darkTheme: darkCodeTheme, 115 | }, 116 | }), 117 | }; 118 | 119 | module.exports = config; 120 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-website", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "docusaurus": "docusaurus", 7 | "start": "docusaurus start", 8 | "build": "docusaurus build", 9 | "swizzle": "docusaurus swizzle", 10 | "deploy": "docusaurus deploy", 11 | "clear": "docusaurus clear", 12 | "serve": "docusaurus serve", 13 | "write-translations": "docusaurus write-translations", 14 | "write-heading-ids": "docusaurus write-heading-ids" 15 | }, 16 | "dependencies": { 17 | "@docusaurus/core": "2.4.1", 18 | "@docusaurus/preset-classic": "2.4.1", 19 | "@mdx-js/react": "^1.6.22", 20 | "clsx": "^1.2.1", 21 | "prism-react-renderer": "^1.3.5", 22 | "react": "^17.0.2", 23 | "react-dom": "^17.0.2" 24 | }, 25 | "devDependencies": { 26 | "@docusaurus/module-type-aliases": "2.4.1" 27 | }, 28 | "browserslist": { 29 | "production": [ 30 | ">0.5%", 31 | "not dead", 32 | "not op_mini all" 33 | ], 34 | "development": [ 35 | "last 1 chrome version", 36 | "last 1 firefox version", 37 | "last 1 safari version" 38 | ] 39 | }, 40 | "engines": { 41 | "node": ">=16.14" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /sidebars.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ 2 | const sidebars = { 3 | tutorialSidebar: [{ type: 'autogenerated', dirName: '.' }], 4 | }; 5 | 6 | module.exports = sidebars; 7 | -------------------------------------------------------------------------------- /src/components/HomepageFeatures/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import clsx from 'clsx'; 3 | import styles from './styles.module.css'; 4 | 5 | const FeatureList = [ 6 | { 7 | title: 'My Notebook', 8 | Svg: require('@site/static/img/personal_notebook.svg').default, 9 | description: ( 10 | <> 11 | This is not just a website; it's my personal ReactJS notebook. 12 | Dive into the pages filled with my experiences, code snippets, 13 | and lessons learned as I master ReactJS. 14 | 15 | ), 16 | }, 17 | { 18 | title: 'Comprehensive ReactJS Insights', 19 | Svg: require('@site/static/img/react_i.svg').default, 20 | description: ( 21 | <> 22 | Explore a treasure trove of ReactJS knowledge on my website. It's where I compile my insights, 23 | tips, and discoveries, making it a valuable resource for anyone on their ReactJS journey. 24 | 25 | ), 26 | }, 27 | { 28 | title: 'Learn with Me', 29 | Svg: require('@site/static/img/code_review.svg').default, 30 | description: ( 31 | <> 32 | Join me on my ReactJS learning adventure. Together, we'll navigate the intricacies of ReactJS, 33 | sharing our challenges and triumphs. My website is your partner in this exciting journey. 34 | 35 | ), 36 | }, 37 | ]; 38 | 39 | function Feature({ Svg, title, description }) { 40 | return ( 41 |
42 |
43 | 44 |
45 |
46 |

{title}

47 |

{description}

48 |
49 |
50 | ); 51 | } 52 | 53 | export default function HomepageFeatures() { 54 | return ( 55 |
56 |
57 |
58 | {FeatureList.map((props, idx) => ( 59 | 60 | ))} 61 |
62 |
63 |
64 | ); 65 | } 66 | -------------------------------------------------------------------------------- /src/components/HomepageFeatures/styles.module.css: -------------------------------------------------------------------------------- 1 | .features { 2 | display: flex; 3 | align-items: center; 4 | padding: 2rem 0; 5 | width: 100%; 6 | } 7 | 8 | .featureSvg { 9 | height: 200px; 10 | width: 200px; 11 | } 12 | -------------------------------------------------------------------------------- /src/css/custom.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --ifm-color-primary: #fa583c; 3 | --ifm-color-primary-dark: #f93e1e; 4 | --ifm-color-primary-darker: #f9310f; 5 | --ifm-color-primary-darkest: #d42405; 6 | --ifm-color-primary-light: #fb725a; 7 | --ifm-color-primary-lighter: #fb7f69; 8 | --ifm-color-primary-lightest: #fca697; 9 | --ifm-code-font-size: 95%; 10 | --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); 11 | } 12 | 13 | [data-theme='dark'] { 14 | --ifm-color-primary: #fa583c; 15 | --ifm-color-primary-dark: #f93e1e; 16 | --ifm-color-primary-darker: #f9310f; 17 | --ifm-color-primary-darkest: #d42405; 18 | --ifm-color-primary-light: #fb725a; 19 | --ifm-color-primary-lighter: #fb7f69; 20 | --ifm-color-primary-lightest: #fca697; 21 | --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); 22 | } 23 | -------------------------------------------------------------------------------- /src/pages/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import clsx from 'clsx'; 3 | import Link from '@docusaurus/Link'; 4 | import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; 5 | import Layout from '@theme/Layout'; 6 | import HomepageFeatures from '@site/src/components/HomepageFeatures'; 7 | 8 | import styles from './index.module.css'; 9 | 10 | function HomepageHeader() { 11 | const { siteConfig } = useDocusaurusContext(); 12 | return ( 13 |
14 |
15 |

{siteConfig.title}

16 |

{siteConfig.tagline}

17 |
18 | 21 | Get started 22 | 23 |
24 |
25 |
26 | ); 27 | } 28 | 29 | export default function Home() { 30 | return ( 31 | 33 | 34 |
35 | 36 |
37 |
38 | ); 39 | } 40 | -------------------------------------------------------------------------------- /src/pages/index.module.css: -------------------------------------------------------------------------------- 1 | .heroBanner { 2 | padding: 4rem 0; 3 | text-align: center; 4 | position: relative; 5 | overflow: hidden; 6 | } 7 | 8 | @media screen and (max-width: 996px) { 9 | .heroBanner { 10 | padding: 2rem; 11 | } 12 | } 13 | 14 | .buttons { 15 | display: flex; 16 | align-items: center; 17 | justify-content: center; 18 | } 19 | -------------------------------------------------------------------------------- /static/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mutasim77/ReactJS-Notebook/68d78c13588845b149af6e080a9ee7e30c975fe1/static/.nojekyll -------------------------------------------------------------------------------- /static/img/code_review.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/img/code_snippets.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/img/docusaurus-social-card.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mutasim77/ReactJS-Notebook/68d78c13588845b149af6e080a9ee7e30c975fe1/static/img/docusaurus-social-card.jpg -------------------------------------------------------------------------------- /static/img/docusaurus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mutasim77/ReactJS-Notebook/68d78c13588845b149af6e080a9ee7e30c975fe1/static/img/docusaurus.png -------------------------------------------------------------------------------- /static/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mutasim77/ReactJS-Notebook/68d78c13588845b149af6e080a9ee7e30c975fe1/static/img/favicon.ico -------------------------------------------------------------------------------- /static/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mutasim77/ReactJS-Notebook/68d78c13588845b149af6e080a9ee7e30c975fe1/static/img/logo.png -------------------------------------------------------------------------------- /static/img/personal_notebook.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/img/react_i.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/img/undraw_docusaurus_mountain.svg: -------------------------------------------------------------------------------- 1 | 2 | Easy to Use 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | -------------------------------------------------------------------------------- /static/img/undraw_docusaurus_tree.svg: -------------------------------------------------------------------------------- 1 | 2 | Focus on What Matters 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | --------------------------------------------------------------------------------