React_03

React_03

You can add the following start and build scripts inside package.json for your ease:

Now, you can simply run the following commands:

npm run start
npm run build

npm start can also be used as a shortcut to npm run start.

Clean console

We can install and use a plugin to remove all our console.* calls:

npm install babel-plugin-transform-remove-console --save-dev

You can add configurations for the above package inside .babelrc file:

{
  "plugins": [["transform-remove-console", { "exclude": ["error", "warn"] }]]
}

Now, if we run the build command and check inside the js file, we won't find any console.log() statements.

Why does React need keys?

Let's say you have an array of items inside any of your components, you may have encountered this warning in the console:

To resolve the warning, you need to give each array item a key — a string or a number that uniquely identifies it among other items in that array. Keys tell React which array item each component corresponds to, so that it can match them up later. This becomes important if your array items can move (e.g. due to sorting), get inserted, or get deleted. A well-chosen key helps React infer what exactly has happened, and make the correct updates to the DOM tree. This is called reconciliation.

Why JSX?

Until now, we have been creating every single element using React.createElement(). Let's understand with the help of an example:

<div class="header">
  <h1>Learning React</h1>
  <ul>
    <li>About Us</li>
    <li>Support</li>
    <li>Home</li>
  </ul>
</div>

The above HTML can be written using pure react this way:

import React from "react";
import ReactDOM from "react-dom/client";

const container = React.createElement(
  "div",
  {
    id: "container",
  },
  [
    React.createElement(
      "h1", 
      {}, 
      "Learning React"
    ),
    React.createElement(
      "ul", 
      {}, 
      [
        React.createElement(
          "li", 
          { key: "li1" }, 
          "About Us"
        ),
        React.createElement(
          "li", 
          { key: "li2" }, 
          "Support"
        ),
        React.createElement(
          "li", 
          { key: "li3" }, 
          "Home"
        ),
      ]
    ),
  ]
);
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(container);

Ha ha ha! What have we created with so much code? Just a structure for a header-container! What if we want to write a big HTML file with header, lots of content and footer? This is just too big and complex to write, read, understand or maintain. There has to be a better way to write this in React. In comes JSX, to the rescue!

What is JSX?

JSX stands for JavaScript XML. JSX has an HTML-like syntax, but it is not HTML inside JavaScript.

This is perfectly valid JavaScript:

The commented code above is the same as the JSX below. We have assigned a JSX expression to heading2.

You may ask, how is this happening? Babel, a javascript compiler, takes in JSX and converts it into our old React.createElement() which is then processed the same way as we've learnt previously:

// JSX => React.createElement() => Object => HTML => DOM

Babel was installed as a dependency when we installed Parcel. You can find it inside node_modules, which itself has a hidden file, .package-lock.json which stores the versions for all the transitive dependencies of the project. This is not to be confused with our project's package-lock.json which is stored in the root directory of our project.

Component

"Everything is a component in React"

There a two ways to write components, class-based components (older way) and functional components (newer way). We'll touch upon class-based components in future.

A functional component is nothing but a function that returns a JSX expression or a React element. Conventionally, the name of a component starts with a capital letter.

import React from "react";
import ReactDOM from "react-dom/client";

const HeaderComponent = () => (
  <div id="container">
    <h1 id="title" key="heading1">
      Hello Everyone from JSX!
    </h1>
    <h1 id="title" key="heading2">
      Hello Everyone!
    </h1>
  </div>
);
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<HeaderComponent />);

Earlier we used to directly pass in our React elements inside our render method, but now since we are using a functional component, we are passing it as a tag inside angular brackets.

Suppose we have any javascript variable (eg: title), we can simply plug it inside our functional component using curly braces:

const title = <h1>Hello All!</h1>;

const HeaderComponent = () => (
  <div id="container">
    {title}
    <h2 id="title" key="heading1">
      Hello Everyone from JSX!
    </h2>
    <h2 id="title" key="heading2">
      Hello Everyone!
    </h2>
  </div>
);

Let's say we had a functional component, we can use it as a tag (component composition):

const Title = () => <h1>Hello All!</h1>;

const HeaderComponent = () => (
  <div id="container">
    <Title />
    <h2 id="title" key="heading1">
      Hello Everyone from JSX!
    </h2>
    <h2 id="title" key="heading2">
      Hello Everyone!
    </h2>
  </div>
);

or simply as a function call, because a functional component is ultimately just a function:

const Title = () => <h1>Hello All!</h1>;

const HeaderComponent = () => (
  <div id="container">
    {Title()}
    <h2 id="title" key="heading1">
      Hello Everyone from JSX!
    </h2>
    <h2 id="title" key="heading2">
      Hello Everyone!
    </h2>
  </div>
);

So, whenever we are using JSX, we can write any javascript expression or variable inside curly braces {}. JSX doesn't blindly run any JavaScript code inside {}, it first sanitises the code to prevent any cross-site scripting attacks.

<MyComponent /> and <MyComponent></MyComponent> are equivalent only when <MyComponent /> has no child components. The opening and closing tags are created to include the child components. For example:

<MyComponent>
    <FirstChildComponent />
    <SecondChildComponent />
    <ThirdChildComponent />
</MyComponent>

That's all for now folks. See you in the next blog!