Close
    Close full mode
    logoYonisfy

    ReactJS

    Git RepositoryContribute on Github
    Last update: 2 months ago by mohammedelzanatyReading time: 42 min

    What's is ReactJS?

    As described

    1. React-js documentation it's a JavaScript library for building user interfaces.
    2. Wikipedia React is a JavaScript library for building user interfaces. It is maintained by Facebook and a community of individual developers and companies. React can be used as a base in the development of single-page or mobile applications, as it is optimal for fetching rapidly changing data that needs to be recorded.

    form the above definitions we noticed that React it's javascript library and this make me ask you

    What's the difference between Library and Framework?

    Both libraries and frameworks are reusable code written by someone else. Their purpose is to help you solve common problems in easier ways.

    We can use a house as a metaphor to explain the difference between these concepts.

    1. Library is like building your home from scratch, you have the choice to make your house as you wish, with any architecture you like, you can sort your rooms in the way you like.
    2. Framework is like buying a new house, you don’t have to deal with building problems, but you can’t choose how to sort your rooms because the house is already built.

    difference between library and framework

    The technical difference between a framework and library lies in a term called inversion of control. When you use a library, you are in charge of the application flow. You choose when and where to call the library. When you use a framework, the framework is in charge of the flow. It provides you with a few places to plug in your code, but it calls the code you plugged in as needed.

    What's the problems that React solve?

    • UI Complexity Solved by Declarative Code
    • Messy Data Flow Solved by Unidirectional Data Flow
    • Slow DOM Operations Solved by virtual-dom-diffing
    • Repetitive Code Solved by Reusable components

    so after we know simple definitions about react and know the problems let's dive into solutions

    https://xbsoftware.com/blog/why-react-awesome-app-dev/

    Composition

    In programming... The composition is about creating small functions and creating bigger and more complete functions with them. Think of a function as a brick, composition is how you would make those bricks work together to build a wall or a house.

    Let's think of composition with another way In mathematics, Function Composition is an operation that takes two functions f and g and produces a function h such that h(x) = g(f(x)) In this operation, the function g is applied to the result of applying the function f to x. That is, the functions f : X → Y and g : Y → Z are composed to yield a function that maps x in X to g(f(x)) in Z.

    You might have encoutered composition in mathematics, written like so: f(g(x)). The function f is composed with the function g of x. Or f after g equals f of g of x. After because we evaluate the functions from right to left, from the inside to the outside:

    f <-- g <-- x

    The output of the precedent function becomes the input of the next. x is the input of g. The output of g(x) becomes the f input.

    I see that things might go to be more complicated so now let's take an example, using map() to create a new array from an initial set of data, and then filtering the result using filter() as a NOTE:map, filter think of them as a factory or containers that given an initial list (array of things), transform it into something else, while keeping that same original list intact.

    const people = ['Mohammed', 'Yasmeen', 'Elzanaty', 'Hamza', 'Saad'];
    people.map(name => name[0]).filter(char => char === 'M'); //'M'

    Declarative Code

    It's an easy and better approach for me, bcoz you let the computer do all that you need for you, you just want to express the logic of a computation without describing its control flow we don't code up all of the steps to get us to the end result. Instead, we declare what we want to be done, and code will take care of doing it.

    const people = ['Mohammed', 'Yasmeen', 'Elzanaty', 'Hamza', 'Saad'];
    const excitedPeople = people.map(name => name + '!');
    // ["Mohammed!", "Yasmeen!", "Elzanaty!", "Hamza!", "Saad!"]

    Imperative Code

    we tell code exactly what to do and how to do it.

    const people = ['Mohammed', 'Yasmeen', 'Elzanaty', 'Hamza', 'Saad'];
    const excitedPeople = [];
    for (let i = 0; i < people.length; i++) {
    excitedPeople[i] = people[i] + '!';
    }
    // ["Mohammed!", "Yasmeen!", "Elzanaty!", "Hamza!", "Saad!"]

    Imperative Code, instructs code for how to perform each step. Declarative code, instructs code for what we want to be done, and let code take care of performing the steps.

    Unidirectional Data Flow

    In general, this (concept)[(https://flaviocopes.com/react-unidirectional-data-flow/)] means that data has one, and only one, way to be transferred to other parts of the application.

    In React this means that:

    • state is passed to the view and to child components
    • actions are triggered by the view
    • actions can update the state
    • the state change is passed to the view and to child components

    view-actions-state

    The view is a result of the application state. State can only change when actions happen. When actions happen, the state is updated.

    Thanks to one-way bindings, data cannot flow in the opposite way (as would happen with two-way bindings, for example), and this has some key advantages:

    it’s less error prone, as you have more control over your data it’s easier to debug, as you know what is coming from where it’s more efficient, as the library already knows what the boundaries are of each part of the system A state is always owned by one Component. Any data that’s affected by this state can only affect Components below it: its children.

    Changing state on a Component will never affect its parent, or its siblings, or any other Component in the application: just its children.

    This is the reason that the state is often moved up in the Component tree, so that it can be shared between components that need to access it.

    Virtual DOM

    First of all — the Virtual DOM was not invented by React, but React uses it and provides it for free.

    The Virtual DOM is an abstraction of the HTML DOM. It is lightweight and detached from the browser-specific implementation details. Since the DOM itself was already an abstraction, the virtual DOM is, in fact, an abstraction of an abstraction.

    The Virtual DOM reflects a tree in which each node is an HTML element. React is able to traverse and carry out operations on this Virtual DOM, saving our app from having "costly" activity on the actual DOM.

    In simple words, virtual DOM is just a copy of the original DOM kept in the memory and synced with the real DOM by libraries such as ReactDOM. This process is called Reconciliation.

    Virtual DOM has the same properties that of the Real DOM, but it lacks the power to directly change the content of the screen.

    Think of Virtual DOM as the blueprint of a machine, changes made to the blueprint doesn't reflects on the machine itself.

    So when there is a update in the virtual DOM, react compares the virtual DOM with a snapshot of the virtual DOM taken right before the update of the virtual DOM.

    With the help of this comparison React figures out which components in the UI needs to be updated. This process is called diffing. The algorithm that is used for the diffing process is called as the diffing algorithm.

    Once React knows which components has been updated, then it replaces the original DOM nodes with the updated DOM node.

    React Virtual DOM Explained in Simple English - Programming with Mosh

    The Diffing Algorithm

    Diffing determines how to make efficient changes to the DOM. With diffing, old DOM nodes are taken out and replaced only when necessary. This way, our app doesn't perform any unnecessary operations to figure out when to render content.

    Pure React

    Let's start by writing pure React. No compile step. No JSX. No Babel. No Webpack or Create-React-App. Just pure Vanilla JavaScript.

    Let's start your project. Create your project directory. I'm going to call mine mz-shop since we're going to be building a shop app throughout this course.

    1. Create a file and name it index.html
    2. put it into a src/ directory inside your project folder.

    In index.html put:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <link rel="stylesheet" href="./style.css" />
    <title>MZ-Shop</title>
    </head>
    <body>
    <div id="root">not rendered</div>
    <script src="https://unpkg.com/react@17.0.1/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@17.0.1/umd/react-dom.development.js"></script>
    <script>
    // Your code is going to go here
    </script>
    </body>
    </html>

    What's new between React 16 and React 17? Nothing! No new features were added. It was a "stepping stone" version that allows sites to upgrade React versions gradually. Previously only one copy of React could run on a page at a time and with v17 more than one can. See more here.

    Now open this file in your browser. On Mac, hit ⌘ (command) + O in your favorite browser, and on Windows and Linux hit CTRL + O to open the Open prompt. Navigate to wherever you saved the file and open it. You should see a line of text saying "not rendered".

    • Pretty standard HTML5 document. If this is confusing, here's a free course from Udacity about HTML and CSS that can help you out.

    • We're adding a root div. We'll render our React app here in a sec. It doesn't have to be called root, just a common practice.

    • We have two script tags.

    • The first is the React library. This library is the interface of how to interact with React; all the methods (except one) will be via this library. It contains no way of rendering itself though; it's just the API.

    • The second library is the rendering layer. Since we're rendering to the browser, we're using React DOM. There are other React libraries like React Native, React 360 (formerly React VR), A-Frame React, React Blessed, and others. You need both script tags. The order is not important.

    • The last script tag is where we're going to put our code. You don't typically do this but I wanted to start as simple as possible. This script tag must come after the other two.

    Let's add some style! Click here to get the stylesheet for this course. If you follow along with the course and use the same class names, the styles will be applied for you automatically. This isn't a course on CSS so I make no assertion it's any good!

    In the last script tag, put the following.

    const App = () => {
    return React.createElement('div', {}, React.createElement('h1', {}, 'MZ Shop'));
    };
    ReactDOM.render(React.createElement(App), document.getElementById('root'));

    This is about the simplest React app you can build.

    • The first thing we do is make our own component, App. React is all about making components. And then taking those components and making more components out of those.

    • There are two types of components, function components and class components. This is a function component. We'll see class components shortly.

    • A function component must return markup (which is what React.createElement generates.)

    • These component render functions have to be fast. This function is going to be called a lot. It's a hot code path.

    • Inside of the render function, you cannot modify any sort of state. Put in functional terms, this function must be pure. You don't know how or when the function will be called so it can't modify any ambient state.

    • React.createElement creates one instance of some component. If you pass it a string, it will create a DOM tag with that as the string. We used h1 and div, those tags are output to the DOM. If we put x-some-custom-element, it'll output that (so web components are possible too.)

    • The second empty object (you can put null too) is attributes we're passing to the tag or component. Whatever we put in this will be output to the element (like id or style.)

    • ReactDOM.render is what takes our rendered App component and puts in the DOM (in our case we're putting it in the root element.)

    • Notice we're using React.createElement with App as a parameter to ReactDOM.render. We need an instance of App to render out. App is a class of components and we need to render one instance of a class. That's what React.createElement does: it makes an instance of a class.

    • Without React Decoration Now that we've done that, let's separate this out from a script tag on the DOM to its own script file (best practice.)

      1. Make a new file in your src directory called App.js and cut and paste your code into it.
      2. Add <script src="App.js"></script> before end of the body at index.html to link js file

    Modify your code, so it looks like:

    const Product = () => {
    return React.createElement('div', {}, [
    React.createElement('h1', {}, 'Mens Cotton Jacket'),
    React.createElement(
    'h2',
    {},
    'Great outerwear jackets for Spring/Autumn/Winter, suitable for many occasions,'
    ),
    React.createElement('h2', {}, '55.99$'),
    ]);
    };
    const App = () => {
    return React.createElement('div', {}, [
    React.createElement('h1', {}, 'MZ Shop'),
    React.createElement(Product),
    React.createElement(Product),
    React.createElement(Product),
    ]);
    };
    ReactDOM.render(React.createElement(App), document.getElementById('root'));

    🚨 You will be seeing a console warning Warning: Each child in a list should have a unique "key" prop. in your browser console. React's dev warnings are trying to help your code run faster. Basically React tries to keep track of components are swapped in order in a list and it does that by you giving it a unique key it can track. If it sees two things have swapped, it'll just move the components instead of re-rendering.

    • To make an element have multiple children, just pass it an array of elements.
    • We created a second new component, the Product component. This component represents one product. When you have distinct ideas represented as markup, that's a good idea to separate that it into a component like we did here.
    • Since we have a new Product component, we can use it multiple times! We just use multiple calls to React.createElement .
    • In createElement, the last two parameters are optional. Since Product has no props or children (it could, we just didn't make it use them yet) we can just leave them off.

    Okay, so we can have multiple product, but it's not a useful component yet as the product contain a lot of properties like title, price, description and image etc. Let's make it a bit more complicated.

    const Product = props => {
    return React.createElement('div', {}, [
    React.createElement('h1', {}, props.title),
    React.createElement('h2', {}, props.description),
    React.createElement('h2', {}, props.price),
    ]);
    };
    const App = () => {
    return React.createElement('div', {}, [
    React.createElement('h1', {}, 'MZ Shop'),
    React.createElement(Product, {
    title: 'Samsung SE450',
    description:
    '21.5-inch desktop business monitor offers superior ergonomics and eco-friendly features – constructed with 30%',
    price: '89.99$',
    }),
    React.createElement(Product, {
    title: 'Mac Book Pro',
    description:
    'our perfect pack for everyday use and walks in the forest. 15 inches) in the padded sleeve, your everyday',
    price: '700$',
    }),
    ]);
    };
    ReactDOM.render(React.createElement(App), document.getElementById('root'));

    Now we have a more flexible component that accepts props from its parent. Props are variables that a parent (App) passes to its children (the instances of Product.) Now each one can be different! Now that is far more useful than it was since this Product component can represent not just Mens Cotton Jacket, but any Product. This is the power of React! We can make multiple, re-usable components. We can then use these components to build larger components, which in turn make up yet-larger components. This is how React apps are made!

    Scaffolding Your React App

    JSX is awesome, but it does need to be transpiled into regular JavaScript before reaching the browser. We typically use a transpire like Babel to accomplish this for us. We can run Babel through a build tool, like Webpack which helps bundle all of our assets (JavaScript files, CSS, images, etc.) for web projects.

    To streamline these initial configurations, we will use Facebook's Create React App package to manage all the setup for us! This tool is incredibly helpful to get started in building a React app, as it sets up everything we need with zero configuration! Install Create React App (through the command-line with npm), and then we can walk through what makes it so great.

    npm install -g create-react-app

    If you're seeing errors when trying to install a package globally, feel free to check out this article in the npm documentation. Note that to find out where global packages are installed, you can run npm list -g in your console (more information here).

    Let's also Set up the API file we will use in the project we will build to make more focus on react I will use a fake api that return products to give us the ability to play with it. you can take a look at it for more information so now we need 4 important function to use

    1. Get Products
    2. Get Product by ID
    3. Delete Product
    4. Search in Products by Query

    so now create a folder in your src folder and name it api then create a new file called ProductAPI.js ad past this code on it.

    const BASE_URL = 'https://fakestoreapi.com';
    /**
    * Get Product by Id
    * @param productId
    * @returns {Promise<any>}
    */
    export const getProductById = productId =>
    fetch(`${BASE_URL}/products/${productId}`)
    .then(res => res.json())
    .then(data => data)
    .catch(error => {
    console.log(error);
    });
    /**
    * Delete Product
    * @param productId
    * @returns {Promise<any>}
    */
    export const deleteProduct = productId =>
    fetch(`${BASE_URL}/products/${productId}`, {
    method: 'DELETE',
    })
    .then(res => res.json())
    .then(data => data)
    .catch(error => {
    console.log(error);
    });
    /**
    * Get All Products
    * @returns {Promise<any>}
    */
    export const getAllProduct = () =>
    fetch(`${BASE_URL}/products`)
    .then(res => res.json())
    .then(data => data)
    .catch(error => {
    console.log(error);
    });
    /**
    * Search in products list
    * @param query
    * @returns {Promise<*>}
    */
    export const searchProduct = async query => {
    const products = await getAllProduct();
    return products.filter(
    product => product.title.toLowerCase().indexOf(query.toLowerCase()) !== -1
    );
    };

    JSX

    So far we've been writing React without JSX, something that I don't know anyone that actually does with their apps. Everyone uses JSX. I show you this way so what JSX is actually doing is demystified to you. It doesn't do hardly anything. It just makes your code a bit more readable.

    If I write React.createElement("h1", { id: "main-title" }, "My Website");, what am I actually trying to have rendered out? <h1 id="main-title">My Website</h1>, right? What JSX tries to do is to shortcut this translation layer in your brain, so you can just write what you mean. Let's convert Product.js to using JSX. It will look like this:

    import React from 'react';
    const Product = props => {
    return (
    <div>
    <h1>{props.title}</h1>
    <h2>{props.description}</h2>
    <h2>{props.price}</h2>
    </div>
    );
    };
    export default Product;

    I don't know about you, but I find this far more readable. And if it feels uncomfortable to you to introduce HTML into your JavaScript, I invite you to give it a shot until the end of the workshop. By then it should feel a bit more comfortable. And you can always go back to the old way.

    However, now you know what JSX is doing for you. It's just translating those HTML tags into React.createElement calls. That's it. Really. No more magic here. JSX does nothing else. Many people who learn React don't learn this.

    Notice the strange {props.title} syntax: this is how you output JavaScript expressions in JSX. An expression is anything that can be the right side of an assignment operator in JavaScript, e.g. const x = <anything that can go here>. If you take away the {} it will literally output props.title to the DOM.

    Notice you still have to import React despite React not being explicitly used. Remember that JSX is compiled to React.createElement calls. Anywhere you use JSX, you need to import React.

    So now JSX is demystified a bit, let's go convert App.js.

    import React, { Component } from 'react';
    import Product from './Product';
    class App extends Component {
    render() {
    return (
    <div>
    <h1>MZ Shop!</h1>
    <Product
    title='Samsung SE450'
    description='desktop business monitor offers superior ergonomics'
    price='89.99$'
    />
    <Product
    title='Mac Book Pro'
    description='Stash your laptop (up to 15 inches) in the padded sleeve,'
    price='700$'
    />
    </div>
    );
    }
    }
    export default App;

    Notice we have Product as a component. Notice that the P in Product is capitalized. It must be. If you make it lowercase, it will try to have product as a web component and not a React component.

    We now pass props down as we add attributes to an HTML tag. Pretty cool.

    💎 3a5a7260aebd28234cac5f63fa27ab3ef5a9f3ca.

    Component Composition

    I remember the first project I made in react and the way of thinking through building the component, just need to create too many components, but I found at the end of the day that this lead to deeply nested structures which made it a pain to pass props all the way down. so now react provide a solution for this by Composition and this lead us to

    What's Composition

    In React, composition is a natural pattern of the component model. It's how we build components from other components, of varying complexity and specialization through props. Depending on how generalized these components are, they can be used in building many other components.

    Reducing Component Nesting With Composition for example here in our application the Product component. each product will have various information about the product including title, price, image and description etc...

    // Product Info Component
    const ProductInfo = ({ id, title, description, price, category }) => {
    return (
    <div className='product-details'>
    <h3 className='product-title'>{title}</h3>
    <ProductPriceCategory price={price} category={category} />
    <p className='product-description'>{description}</p>
    </div>
    );
    };
    // ProductCategory And PriceComponent
    const ProductPriceCategory = ({ price, category }) => {
    return (
    <div className='product-meta'>
    <h4 className='product__price'>{price}</h4>
    <p className='product__category'>{category}</p>
    </div>
    );
    };

    so we can do this better here to reduce the nested structure by using props.children and by handling specialization through props.

    // Product.js
    import React from 'react';
    // Product Card Component
    const Product = props => {
    return (
    <div className='product'>
    {props.product.image && (
    <img
    src={props.product.image}
    className='product-avatar'
    alt={`product of ${props.product.title}`}
    />
    )}
    {props.children}
    <div
    className='product-remove'
    onClick={() => {
    props.onDeleteProduct(props.product.id);
    }}
    >
    remove
    </div>
    </div>
    );
    };
    export default Product;

    so now before we continue I have a question

    What's Props Children

    The React docs say that you can use props.children on components that represent generic boxes and that ‘don’t know their children ahead of time’. For me, that did not really clear things up. I’m sure for some, that definition makes perfect sense, but it did not for me. My simple explanation of what this.props.children does is that

    it is used to display whatever you include between the opening and closing tags when invoking a component.

    A simple example Here’s an example of a stateless function that is used to create a component. Again, since this is a stateless function, there is no 'this' keyword so just use props.children

    const Product = props => {
    return (
    <div>
    <h1>Zanaty</h1>
    {props.children}
    </div>
    );
    };

    This component contains an <h1> that is receiving some props, and then it is displaying {props.children}. Whenever this component is invoked{props.children} will also be displayed and this is just a reference to what is between the opening and closing tags of the component.

    so let's back to our code and create a product card in Product.js

    import React from 'react';
    const Product = ({ title, image, description, price, category }) => {
    return (
    <div className='product'>
    {image && <img src={image} className='product-avatar' alt={`product of ${title}`} />}
    <div className='product-details'>
    <h3 className='product-title'>{title}</h3>
    <div className='product-meta'>
    <p className='product-price'>{price}</p>
    <p className='product-category'>{category}</p>
    </div>
    <p className='product-description'>{description}</p>
    </div>
    <div className='product-remove'>remove</div>
    </div>
    );
    };
    export default Product;

    but now as we add more props to our code we need to edit the Product component at App.js like

    import React, { Component } from 'react';
    import Product from './Product';
    class App extends Component {
    render() {
    return (
    <div>
    <div className='product-list'>
    <Product
    title='Fjallraven - Foldsack No. 1 Backpack, Fits 15 Laptops'
    description='Your perfect pack for everyday use and walks in the forest. '
    price='89.99$'
    category='men clothing'
    image='https://fakestoreapi.com/img/81fPKd-2AYL._AC_SL1500_.jpg'
    />
    <Product
    title='Mens Casual Premium Slim Fit T-Shirts'
    description='Slim-fitting style, contrast raglan long sleeve, three-button henley placket,'
    price='89.99$'
    category='men clothing'
    image='https://fakestoreapi.com/img/71-3HjGNDUL._AC_SY879._SX._UX._SY._UY_.jpg'
    />
    </div>
    </div>
    );
    }
    }
    export default App;

    What are some benefits of this change? We now have code (the Card component) that is more reusable as a result of it being generalized. We create the specialized cards ProductCard by passing props through Card. We made our overall code cleaner by unifying individual components that are not reusable, resulting in a simpler structure that doesn't require passing props down through many components.

    In general I find two reasons to break a component into smaller components: reusability and organization. When you want to use the same component in multiple places (e.g. a button, a tool tip, etc.) then it's helpful to have one component to maintain, test, use, etc.

    Other times it can be useful to break concepts down into smaller concepts to make a component read better. For example, if we put all the logic for this entire page into one component, it would become pretty hard to read and manage. By breaking it down we can make each component easier to understand when you read it and thus maintain.

    Looks much better! The links don't go anywhere yet but we'll get there. We don't have a good loading experience yet though. Right now we just seem unresponsive. Using a new tool to React called Suspense we can make the DOM rendering wait until we finish loading our data, show a loader, and then once it finishes we can resume rendering it. This is coming soon; for now you would just keep track of a loading Boolean and then conditionally show your component or a loading spinner based on whether it was finished loading or not.

    It's important to note that this is just a demonstration of a concept and by no means the 'right' way. Depending on your needs, you may compose your components differently.

    I hear you enough working with static data and let's make stuff more dynamically from the backend 📝 NOTE in the commited code you will find CSS I add to make thing looks nicer

    💎 6e1a7c36dec7eb028b8c46efe790c93f6f7ae9d9.

    State and Lifecycle Methods with React

    Before dig deeper and dive for getting data from the api let's clear some important concepts and make sure we understand it well one of these important concepts is state so what's the state

    State

    As ReactDoc

    • plain JavaScript object
    • managed within the component (similar to variables declared within a function).
    • can only be used in Class Components
    • can be updated only by a setState function which schedules an update to a component’s state object. When state changes, the component responds by re-rendering.

    so it define the state in the class component it defined as property of the component class for example:-

    class App extends Component {
    // ...
    state = {};
    // ...
    }

    and can be updated with setState by passing an object or a function in setState?

    Passing an update function allows you to access the current state value inside the updater. Since setState calls are batched, this lets you chain updates and ensure they build on top of each other instead of conflicting:

    // this give you access to the previous state
    this.setState((prevState) => ({ ... }))
    OR
    this.setState({ ... })

    📝 props get passed to the component (similar to function parameters) and it's immutable i.e. once set the props cannot be changed,

    Should this Component have state?

    state is optional. Since state increases complexity and reduces predictability, a Component without state is preferable. Even though you clearly can't do without state in an interactive app, you should avoid having too many Stateful Components.

    Component types

    1. Stateless Component — Only props, no state. There's not much going on besides the render() function and all their logic revolves around the props they receive. This makes them very easy to follow (and test for that matter). We sometimes call these dumb-as-f*ck Components (which turns out to be the only way to misuse the F-word in the English language).
    2. Stateful Component — Both props and state. We also call these state managers. They are in charge of client-server communication (XHR, web sockets, etc.), processing data and responding to user events. These sort of logistics should be encapsulated in a moderate number of Stateful Components, while all visualization and formatting logic should move downstream into as many Stateless Components as possible.

    so for now we need to statue our products in the app and initialize it with empty array for now

    class App extends Component {
    state = {
    products: [],
    };
    render() {
    // ...
    }
    }

    the next step will be get the data from the API and this will lead us to other important concept

    The Component Lifecycle

    As ReactDoc

    • Each component has several “lifecycle methods” that you can override to run code at particular times in the process.
    • You can use this lifecycle diagram as a cheat sheet. In the list below, commonly used lifecycle methods are marked as bold. The rest of them exist for relatively rare use cases.

    The diagram below is from the official React documentation showcasing the different React lifecycle methods and when they are invoked.

    so there're three phases:

    1. Mounting: Adding nodes to the DOM
    2. Updating: Altering existing nodes in the DOM
    3. Un Mounting: Removing nodes from the DOM

    every component goes through and to put it in simple terms, you can think of the React component lifecycle as the “lifetime” of a component. Lifecycle methods are series of events that happen throughout the birth, growth, and death of a React component.

    let's think a little here what we need to achieve in simple words get products and parse it to the DOM so logically we are in the mounting phase there's a lot of stuff happen here but for now let focus on componentDidMount which invoked immediately after a component is mounted (inserted into the tree). Initialization that requires DOM nodes should go here. see more

    If you need to load data from a remote endpoint, this is a good place to instantiate the network request.

    to apply this at our code

    import React, { Component } from 'react';
    import { getAllProduct } from './api/ProductAPI';
    class App extends Component {
    state = {
    products: [],
    };
    componentDidMount() {
    // get products
    getAllProduct().then(products => {
    if (Array.isArray(products)) {
    this.setState({ products });
    }
    });
    }
    render() {
    return (
    <div>
    <div className='product-list'>
    <pre>
    <code>{JSON.stringify(this.state, null, 2)}</code>
    </pre>
    </div>
    </div>
    );
    }
    }
    export default App;
    • Whenever a class gets created (React or not), the constructor gets called. If you don't create a constructor, there's a default one that silently gets run in the background. Inside we accept the props from whatever parent created it and then call super(props) since we need to take those props and hand them to React.

    • We initiate state here. We are going to be keeping an array of products data that we load from the API. We'll initialize that as an empty array so we never have to check if that array exists or not.

    • We're calling getAllProduct method. This lets us get all available products.

    • Now, after the response comes back from the API, we call a method called setState. setState takes in an object and does a shallow merge with your current state.

    • Now we take that API data and output that to the DOM. Notice React is smart enough to re-render itself after a setState is called. pre and code are two tags that allow you to output that code pre-formatted.

    Let's make the app use the Product Component we made

    import React, { Component } from 'react';
    import { getAllProduct } from './api/ProductAPI';
    import Product from './Product';
    class App extends Component {
    state = {
    products: [],
    };
    componentDidMount() {
    // get products
    getAllProduct().then(products => {
    if (Array.isArray(products)) {
    this.setState({ products });
    }
    });
    }
    render() {
    return (
    <div>
    <div className='product-list'>
    {this.state.products &&
    this.state.products.map(product => (
    <Product
    title={product.title}
    image={product.image}
    price={product.price}
    category={product.category}
    description={product.description}
    />
    ))}
    </div>
    </div>
    );
    }
    }
    export default App;

    📝 We use map which takes a JavaScript array, takes a function, applies that function to each array item (i.e. if you have an array of length 15, that function gets called 15 times,) and returns a new array containing the results of each of those function called. In

    const x = [1,2,3].map(num => num * 2); // [2,4,6]

    In this case, we have an array of numbers, and we transform those into other thing.

    if you open your console now you will find Warning: Each child in a list should have a unique "key" prop. because Key is a unique identifier that we give React, so it can do quick comparisons on objects. If we decide to change how we sort the list of products.

    Ex. we sort by title instead of price, we'd re-arrange all the object but they'd be the same object. All React knows is it got a new list. Without any further hinting, React would just destroy all the DOM objects and start over. If we give it a unique key for each object, it can track that an object just moved positions and didn't actually get destroyed and just move the DOM object instead of re-rendering. Big performance win. so to achieve this and remove warning so the map will

    this.state.products.map(product => (
    <Product
    key={product.id} /* this line added */
    title={product.title}
    image={product.image}
    price={product.price}
    category={product.category}
    description={product.description}
    />
    ));

    💎 39c564868e4c0e2fc1dc5c609b7481e94c72a9ea.

    Handling User Input

    HTML form elements work a little bit differently from other DOM elements in React, because form elements naturally keep some internal state. For example, this form in plain HTML accepts a single name:

    <form>
    <label>
    Name:
    <input type="text" name="name" />
    </label>
    <input type="submit" value="Submit" />
    </form>

    This form has the default HTML form behavior of browsing to a new page when the user submits the form. If you want this behavior in React, it just works. But in most cases, it’s convenient to have a JavaScript function that handles the submission of the form and has access to the data that the user entered into the form. The standard way to achieve this is with a technique called “controlled components”. ➡ Read More @ ReactDoc

    Controlled Components

    A Controlled Component is one that takes its current value through props and notifies changes through callbacks like onChange. A parent component "controls" it by handling the callback and managing its own state and passing the new values as props to the controlled component. You could also call this a "dumb component".

    For example, , we can write the form that give user ability to search in the products as a controlled component:

    import React, { Component } from 'react'
    class App extends Component {
    // 1 -> declare the state
    // With a controlled component, the input’s value is always driven by the React state.
    // While this means you have to type a bit more code,
    // you can now pass the value to other UI elements too, or reset it from other event handlers.
    state = {
    query: ''
    }
    handleSearchProduct = query => {
    this.setState(() => ({
    query: query.trim()
    }))
    }
    render() {
    const { query } = this.state
    return (
    <div className="list-products">
    <div className="list-products-top">
    <input
    className="search-products"
    type="text"
    placeholder="Search Products"
    // Since the value attribute is set on our form element, the displayed value will always be this.state.query,
    value={query}
    // on change event that take care of any changes happen in the input
    // making the React state the source of truth.
    // Since handleChange runs on every keystroke to update the React state,
    // the displayed value will update as the user types.
    onChange={event => {
    this.handleSearchProduct(event.target.value)
    }}
    />
    </div>
    // ...
    </div>
    )
    }
    }
    export default App

    Uncontrolled Component

    A Uncontrolled Component is one that stores its own state internally, and you query the DOM using a ref to find its current value when you need it. This is a bit more like traditional HTML.

    To write an uncontrolled component, instead of writing an event handler for every state update, you can use a ref to get form values from the DOM.

    For example, this code accepts a single name in an uncontrolled component:

    import React, { Component, createRef } from 'react'
    class App extends Component {
    constructor(props) {
    super(props);
    this.input = createRef();
    }
    handleSearchProduct = event => {
    alert('A name was submitted: ' + this.input.current.value);
    event.preventDefault();
    }
    render() {
    const { query } = this.state
    return (
    <div className="list-products">
    <div className="list-products-top">
    <input
    className="search-products"
    type="text"
    placeholder="Search Products"
    ref={this.input}
    />
    </div>
    // ...
    </div>
    )
    }
    }
    export default App

    Conclusion

    Both the controlled and uncontrolled form fields have their merit. Evaluate your specific situation and pick the approach — what works for you is good enough.

    Featureuncontrolledcontrolled
    one-time value retrieval (e.g. on submit)
    validating on submit
    instant field validation
    conditionally disabling submit button
    enforcing input format
    several inputs for one piece of data
    dynamic inputs

    If your form is incredibly simple in terms of UI feedback, uncontrolled with refs is entirely fine. You don’t have to listen to what the various articles are saying is “bad.”

    Also, this is not an once-and-for-all decision: you can always migrate to controlled inputs. Going from uncontrolled to controlled inputs is not hard.

    I am not going into all the ways of handling user interactions in JavaScript. You can register handlers for things mouse leave, mouse enter, key up, key down, and can even handle stuff like copy and paste events, focus, blur, etc. Here's a list of them from the React docs.

    💎 02045ab8b4c6fa78f3dd105a375b5f4934bde8c8.

    Props Types

    I spent a lot of time to ask myself why I use this? and to not hide a secret from you, it was a heavy burden on my shoulders but in simple words this little package will save you from a lot shitty stuff with just multiple lines of code and the most important thing is that it will save you from yourself

    prop-types is a runtime checking for react props and similar objects.

    How React props work

    React props allow you to send data — including numbers, strings, functions, objects, arrays, etc. — to a component when you call on that component. If you have multiple components, you can pass data from one component to another.

    To pass props between components, you would add them when the component is called, just as you would pass arguments when calling on a regular JavaScript function. for more information, check out react props docs

    Why validate props in React?

    When developing a React application, you might encounter the need for a prop to be structured and defined to avoid bugs and errors. Just like a function might have mandatory arguments, a React component might require a prop to be defined, otherwise, it will not render properly. If you forget to pass a required prop into a component that needs it, it could cause your app to behave unexpectedly.

    Using the prop-types library in React

    Prior to React 15.5.0, a utility named PropTypes was available as part of the React package, which provided a lot of validators for configuring type definitions for component props. It could be accessed with React.PropTypes.

    However, in later versions of React, this utility has been moved to a separate package named prop-types, so you need to add it as a dependency for your project in order to get access to the PropTypes utility.

    npm install prop-types --save

    It can be imported into your project files as follows:

    import PropTypes from 'prop-types';

    then you will be able to use by different validators provided and now I think it's an appropriate time to check how we can add prop-types to the Product.js component

    💎 ea00c52a8ddd3440c75581d34637da3d5e051879.

    Presentational and Container Component

    💎 b678eae9198cddb3a7b7119265bf02e57e496962.

    React Dev Tools

    React has some really great tools to enhance your developer experience. We'll go over a few of them here.

    NODE_ENV=development

    React already has a lot of developer conveniences built into it out of the box. What's better is that they automatically strip it out when you compile your code for production.

    So how do you get the debugging conveniences then? Well, if you're using Parcel.js, it will compile your development server with an environment variable of NODE_ENV=development and then when you run parcel build <entry point> it will automatically change that to NODE_ENV=production which is how all the extra weight gets stripped out.

    Why is it important that we strip the debug stuff out? The dev bundle of React is quite a bit bigger and quite a bit slower than the production build. Make sure you're compiling with the correct environmental variables or your users will suffer.

    Strict Mode

    React has a new strict mode. If you wrap your app in <React.StrictMode></React.StrictMode> it will give you additional warnings about things you shouldn't be doing. I'm not teaching you anything that would trip warnings from React.StrictMode but it's good to keep your team in line and not using legacy features or things that will be soon be deprecated.

    Go to App.js and wrap <App /> in the render call in <StrictMode>.

    // import at top
    import { StrictMode } from 'react';
    // replace render
    render(
    <StrictMode>
    <App />
    </StrictMode>,
    document.getElementById('root')
    );

    Dev Tools

    React has wonderful dev tools that the core team maintains. They're available for both Chromium-based browsers and Firefox. They let you do several things like explore your React app like a DOM tree, modify state and props on the fly to test things out, tease out performance problems, and programtically manipulate components. Definitely worth downloading now.

    Acknowledgment

    I am not writing all the content here, most of the explanations based on the workshop Brian Holt ©
    🛠️ Technologies — Previous
    Warm up Before React
    Next — 🛠️ Technologies
    React with TypeScript