DEV Community

Kemi Owoyele
Kemi Owoyele

Posted on

INTRODUCTION TO REACT JS

React is a JavaScript library used to create interactive single page applications. In traditional websites, every click to page links is fetched from the server in the backend. React and other single page applications introduced ways in which every of that could be handled in the browser. A single index html page is fetched from the server, and in the case of react, react will handle all other page loads from the front end.
Creating an app with react is often done with the command line tool. React requires some configurations and setups that come with the tool. To use this tool, a modern version of node js must be installed in your computer. To confirm if you have node in your computer, open any terminal in your computer. If you are on windows, open the command prompt (cmd) and type
node –v

Image description
If a version is displayed to you, it means you have node installed in your computer. Also if the version you have is less than 5.2, you need to install a newer version. If you don’t have it, go to nodejs.org and install the latest version.
Still in the terminal, navigate into the directory you want to create the project. Type in
npx create-react-app projectName
npx will run the code on the internet and install a new react project with the name we put in place of projectName above. Press enter and wait for a while for it to create the project for you. Once done,
cd into the new project and type
npm start
To view the starter project, you can then open up the project in your text editor.
Most of the files we are going to work with are going to be in the public folder.
The index.html file is the only html file that will be returned from the server. In this file, there is a div with id of root that will be mounted on react. This div will render all of our js codes as appropriate. You are not expected to do anything on this file, as what needs to be done is already taken care of by the create-react-app.
Another important file is the main.js or insex.js file. This file is where the root element is mounted to the reactDOM. It is also responsible for rendering the root component. You are also to leave this file as it is.
The App.js file is the root component file. This is where you can create your own component. The follow come component is already rendering some default react stuff. You may erase all that and replace with what you desire to render.
To view your page on the browser, you spin up the local development server by typing in the terminal;
npm run start
When it’s done spinning, it will give you an address that you can use to view your page on the browser. In most cases, the address is
➜ Local: http://localhost:3000/

jsx

React codes are written in JavaScript. Though some of the codes will appear as html codes, they are actually jsx codes. Jsx is a special type of JavaScript code for situations like this. This jsx codes will be converted to HTML by the babel transpiler.

React components

React components are autonomous segment of content. They usually contain their own logic and html like templates. For example, on a web page, the header, footer, segments and articles could be reusable separate components.
To create a react component;

import "./App.css";

function App() {

  return (
    <>
      <div className="container">
        <h1>This is my first react App</h1>
      </div>
    </>
  );
}

export default App;


Enter fullscreen mode Exit fullscreen mode

Declare a function with the name of the function starting with a capital letter, then use the return keyword to return the jsx code. Then export the component so it can be accessible to other components or the root page.
Inside the return statement, the jsx codes wrapped in () will be rendered on the browser as html.
The above code will be rendered in the browser like so;

Image description
The import code below was used to link the page to a css file which is responsible for the style you see on the above image.
import "./App.css";

Fragment

In each component, only one root element can be rendered. Hence, having code like the one below, will throw an error.

  return (

      <div className="container">
        <h1>This is my first react App</h1>
      </div>
      <div>
        another div
      </div>
  );

Enter fullscreen mode Exit fullscreen mode

This is usually avoided by wrapping the entire containing elements in a fragment tag. The fragment tag does not add extra HTML element to the DOM. It can be written as

return (
    <Fragment>
      <div className="container">
        <h1>This is my first react App</h1>
      </div>
      <div>another div</div>
    </Fragment>
  );

Enter fullscreen mode Exit fullscreen mode

But it is usually written as

return (
    <>
      <div className="container">
        <h1>This is my first react App</h1>
      </div>
      <div>another div</div>
    </>
  );

Enter fullscreen mode Exit fullscreen mode

Outputting dynamic values

jsx allows us to output data in dynamic form without needing to hard code the data. To output dynamic data, you can create a variable inside the function, before the return keyword. You can also write any JavaScript code you wish to use in this space. To output the variable, we wrap the variable name in curly braces at the part of the jsx we want it outputted.

function App() {
  const myLocation = "I live in Abuja";
  return (
    <>
      <div className="container">
        <h1> {myLocation} </h1>
      </div>
    </>
  );
}

Enter fullscreen mode Exit fullscreen mode

Image description
With this format, we can output as many values as we desire in our component.

import "./App.css";
function App() {
  const myLocation = "Abuja";
  const myName = "Kemi Owoyele";
  const myJob = "I am a software developer";
  return (
    <>
      <div className="container">
        <h1>my name is {myName}</h1>
        <h1>I Live in {myLocation} </h1>
        <h1>{myJob}</h1>
      </div>
    </>
  );
}

export default App;


Enter fullscreen mode Exit fullscreen mode

Image description

You can output an array with this method; the only difference is that it will be converted to a string.

function App() {
  const myLocation = "Abuja";
  const myName = "Kemi Owoyele";
  const myJob = "I am a software developer";
  const skills = ["CSS ", "HTML ", "JS ", "REACT"];
  return (
    <>
      <div className="container">
        <h1>My name is {myName}</h1>
        <h1>I Live in {myLocation} </h1>
        <h1>{myJob}</h1>
        <h1>My skills are {skills}</h1>
      </div>
    </>
  );
}

Enter fullscreen mode Exit fullscreen mode

Image description
The exception however, is with objects and Booleans.

function App() {
  const aboutMe = {name: 'Kemi Owoyele',job: 'software developer', location: 'Abuja'};
    return (
    <>
      <div className="container">
        <h1> {about Me}</h1>
      </div>
    </>
  );
}


Enter fullscreen mode Exit fullscreen mode

Image description
We can also output dynamic values directly in the curly braces;

function App() {
  return (
    <>
      <div className="container">
        <h1> {5 + 10 / 2}</h1>
      </div>
    </>
  );
}

Enter fullscreen mode Exit fullscreen mode

10
We can also use dynamic values as HTML attributes.

Multiple components

A component is a function that returns a jsx template and is exported at the bottom of the file.
A react app is made up of a component tree with the root component as the origin point of the other components. The root component is like the home page to which other components link. Not all components must link directly to the root component.

component tree

The root component as given to us by the create react app tool is the App.js component. This is the component that is rendered in the main.js or index.js file.

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.js'
import './index.css'

ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
)

Enter fullscreen mode Exit fullscreen mode

To create our own component, say the Navbar component for example. We will need to create a new file in the source folder and name it Navbar.js. In large projects, you may prefer to create a components folder, and in that folder you can have your Navbar.js file. The name of the file is usually written with uppercase as the first character.
In that file, create the component function as we showed above, and do not forget to export the function at the bottom. The first character of the name of the component function is also to be in uppercase.
Navbar.js file

function Navbar() {
  return (
    <>
      <nav>
        <div>React App</div>
        <div className="nav-links">
          <a href="/">Home </a>
          <a href="/">Contact </a>
          <a href="/">About </a>
        </div>
      </nav>
    </>
  );
}

export default Navbar;

Enter fullscreen mode Exit fullscreen mode

Then import the component to the App component using the import statement and render the component where you want it to be. To render the component, you will write the name of the component like an HTML tag. Ensure that the tag is closed properly or you will get an error. You may use a self-closing tag though.
App.js file

import Navbar from "./Navbar";

function App() {
  return (
    <>
        <Navbar />
    </>
  );
}

export default App;


Enter fullscreen mode Exit fullscreen mode

Image description

You can still create another component and nest it in the Navbar component. Just follow the same procedure.

Adding CSS style

To use a CSS file with react, import css file to the js page you want it to refer to. It is common practice to have separate CSS files for each component. This is not absolutely necessary because whether a file is imported to one component does not mean that the styles are scoped to that component.
import "./nav.css";
For small project like the one we are building, we may as well stick to the index.css file. Index.css file came with the create react app tool, and has already been imported to the main.jsx file.
Add inline styling
To add inline styling in react, a couple of rules apply;
• Rather than write the styles in quotes like you would have done with inline html, you will use double curly braces.
<nav style={{}}>
• The style values are writing inside quote like so;
color: "#99023c"

• Style properties like background-color that is separated with – sign are camel cased instead as javascript will mistake the – as a minus operator.
backgroundColor: rgb(250, 169, 230),

• Styles are separated with comma instead of semi colon as done with inline HTML

style={{
          color: "#99023c",
          backgroundColor: rgb(250, 169, 230),
          width: "100vw",
        }}

Enter fullscreen mode Exit fullscreen mode

Click events

React support different types of events available in javascript. To handle a click event, create the handleClick function or whatever name for the function inside the component function, but above the return statement. Then you can reference the function in your jsx. Take note not to invoke the function with (), because it will be automatically invoked by react before the click. You are only to reference the function.

const Home = () => {
  const handleClick = () => {
    console.log("You clicked me");
  };
  return (
    <>
      <div className="home">this is the home component</div>
      <button onClick={handleClick}>Click Me</button>
    </>
  );
};

export default Home;


Enter fullscreen mode Exit fullscreen mode

If however, you intend to insert a parameter to the handle click reference, you will have to wrap your reference in an anonymous function. That way you can pass your parameters without hassle.

const Home = () => {
  const handleClick = (num) => {
    console.log(`you get ${num} score per click`);
  };
  return (
    <>
      <div className="home">
        <h3>this is the home component</h3>
        <button
          onClick={() => {
            handleClick(5);
          }}
        >
          Click Me
        </button>
      </div>
    </>
  );
};

export default Home;


Enter fullscreen mode Exit fullscreen mode

Image description

Using state (usestate hook)

State of a component basically means the data being used by that component at a particular point in time. Why state management is an issue in react is that react does not watch changes in variables for re-rendering. Rather in react data should be immutable. To make those variables reactive and renderable with react, we use the useState hook.
To have access to the useState hook, you go to the top of your component page, before the function and import useState from react.
import { useState } from "react";
The useState is a function, and we can use our initial value as its argument. To have the opportunity to change that value, we have to set the array of the name of the variable and the function for changing that variable to be = useState function. To do this we would destructure the array.
const [number, setNumber] = useState(0);
the setState function may then be used to manipulate the data as desired

import { useState } from "react";

const Home = () => {
  const [number, setNumber] = useState(0);
  const handleClick = () => {
    setNumber(number + 1);
  };
  return (
    <>
      <div className="home">
        <button onClick={handleClick}>Click Me</button>
        <h1>you have clicked {number} times</h1>
      </div>
    </>
  );
};

export default Home;

Enter fullscreen mode Exit fullscreen mode

The value of the state could be any data type.
const [number, setNumber] = useState( 0 );

Outputting Lists

Sometimes, we may need to display a list of objects; we can achieve that by hard coding ul, li items and so. But if the list is expected to be dynamic, and the state is eventually going to be changed, that means hard coding the list would be a bad choice.
To render the list, set the initial variable as the initial argument for the useState function.

const [products, setProducts] = useState([
    { name: "Product 1", description: "lorem 123...", price: "$3.90", id: 1 },
    { name: "Product 2", description: "lorem 123...", price: "$4.90", id: 2 },
    { name: "Product 3", description: "lorem 123...", price: "$.90", id: 3 },
  ]);

Enter fullscreen mode Exit fullscreen mode

Then we can use the map() method to loop through the array and render the outcome.

import { useState } from "react";
const Home = () => {
  const [products, setProducts] = useState([
    { name: "Product 1", description: "lorem 123...", price: "$3.90", id: 1 },
    { name: "Product 2", description: "lorem 123...", price: "$4.90", id: 2 },
    { name: "Product 3", description: "lorem 123...", price: "$.90", id: 3 },
  ]);
  return (
    <>
      <div className="home">
        <ul>
          {products.map((product) => (
            <li className="product-list" key={product.id}>
              <h5> {product.name}</h5>
              {<p> {product.price}</p>}
            </li>
          ))}
        </ul>
      </div>
    </>
  );
};

export default Home;


Enter fullscreen mode Exit fullscreen mode

Image description

Key Attribute

The key attribute is used to identify a particular item on the list. It is useful, in case you need to update or delete a particular item, the key value will be the deciding factor for selecting the specific one to be affected. The key value must unique; no two items should have the same key.

React props

Single page applications are popular for the advantage of reusing components. Props are used to make react components reusable. Props are used to pass in data into the reusable components.
To make our product list component reusable, we want to pull it out to a separate component, and render it in the home component. First, we will create a new file; ProductList.js in the src folder.
In the file, create your basic component structure, don’t forget to export default.

const ProductList = () => {
  return (
    <>
      <div className="products"></div>
    </>
  );
};

export default ProductList;


Enter fullscreen mode Exit fullscreen mode

Next, cut the codes for mapping through the list items and place them inside your return statement in the Product list component

const ProductList = () => {
  return (
    <>
      <div className="products">
        <ul>
          {products.map((product) => (
            <li className="product-list" key={product.id}>
              <h5> {product.name}</h5>
              {<p> {product.price}</p>}
            </li>
          ))}
        </ul>
      </div>
    </>
  );
};

export default ProductList;


Enter fullscreen mode Exit fullscreen mode

Ihen in the home component, import the ProductList component at the top, and nest the component where you want it to be rendered.

import { useState } from "react";
import ProductList from "./ProductList";

const Home = () => {
  const [products, setProducts] = useState([
    { name: "Product 1", description: "lorem 123...", price: "$3.90", id: 1 },
    { name: "Product 2", description: "lorem 123...", price: "$4.90", id: 2 },
    { name: "Product 3", description: "lorem 123...", price: "$.90", id: 3 },
  ]);
  return (
    <>
      <div className="home">
        <ProductList />
      </div>
    </>
  );
};

export default Home;


Enter fullscreen mode Exit fullscreen mode

at this stage, there will be an error because the map method in the ProductList component cannot access the products array in the Home component. This is where props comes to the rescue. They are used to pass data from one component to another.
Where the component is nested in the Home component, we will have to pass in the props property as an attribute.
<ProductList products={products} />

Then we will accept the property in our ProductList component as an argument to the component function.
const ProductList = ({ products }) => {
Note that the argument was destructured, if there were more than one props, you can write them there separating them with comma.
const ProductList = ({ products, title }) => {

<ProductList products={products} title="Available Products" />
products’s value is written in curly braces because it is a dynamic value, while title is written in quotes because it is a direct string.

If we had not detructured the argument, it would have been written as;
const ProductList = (props) => {
Then the properties we intend to pass through the props would be declared afterwards;
`const products = props.products;
const name = props.name;

`
Complete codes for both components will be
Home component

import { useState } from "react";
import ProductList from "./ProductList";

const Home = () => {
  const [products, setProducts] = useState([
    { name: "Product 1", description: "lorem 123...", price: "$3.90", id: 1 },
    { name: "Product 2", description: "lorem 123...", price: "$4.90", id: 2 },
    { name: "Product 3", description: "lorem 123...", price: "$.90", id: 3 },
  ]);
  return (
    <>
      <div className="home">
        <ProductList products={products} title="Available Products" />
      </div>
    </>
  );
};

export default Home;


Enter fullscreen mode Exit fullscreen mode

ProductList component

const ProductList = ({ products, title }) => {
  return (
    <>
      <div className="products">
        <h1>{title}</h1>
        <ul>
          {products.map((product) => (
            <li className="product-list" key={product.id}>
              <h3> {product.name}</h3>
              {<p> {product.price}</p>}
            </li>
          ))}
        </ul>
      </div>
    </>
  );
};

export default ProductList;


Enter fullscreen mode Exit fullscreen mode

Outcome

Image description

You can apply your own CSS as you please.

Reusing components

We will like to create another component that will display only goods that cost less than $10. It will be counterproductive to do this by creating another component for this purpose, especially since we would still want to display the same information in the same format. To achieve this, we will pass in the props to filter out products that cost more than $10.
We can declare a cheapProducts variable above the return statement; and make the variable equal to the filtered array, then pass cheapProducts as a prop value
const cheapProducts = products.filter((product) => product.price < 10);
In our home component, we can pass in the props with cheapProducts.

<ProductList
            products={cheapProducts}
            title="Products less than $10.00"
          />

Enter fullscreen mode Exit fullscreen mode

The full code on the home component

import { useState } from "react";
import ProductList from "./ProductList";

const Home = () => {
  const [products, setProducts] = useState([
    { name: "Product 1", description: "lorem 123...", price: 5.45, id: 1 },
    { name: "Product 2", description: "lorem 123...", price: 9.99, id: 2 },
    { name: "Product 3", description: "lorem 123...", price: 20.0, id: 3 },
  ]);
  const cheapProducts = products.filter((product) => product.price < 10);

  return (
    <>
      <div className="home">
        <ProductList products={products} title="All Products" />
        <div>
          <ProductList
            products={cheapProducts}
            title="Products less than $10.00"
          />
        </div>
      </div>
    </>
  );
};

export default Home;


Enter fullscreen mode Exit fullscreen mode

the ProductList.jsx file has remained untouched
*outcome
*

Image description

You can render this component in as many parent components as possible, what will make a difference will be the value of the props.

Delete item

We want to generate a click event that we can use to delete an item from the array. Create a button with a click event handler in the ProductList component, inside the li. Do not forget to wrap the function in an anonymous function so we can pass in arguments.
<button onClick={() => handleDelete(product.id)}>Delete</button>

We would need to create a function to handle the click event. But the function would be better if created in the parent home component where we can use the useState hook to update the component. create a new variable inside the handleDelete function to hold the filtered arrays. Then to make it reactive, use as an argument in the useState function which in this case is setProducts.

 const handleDelete = (id) => {
    const newProducts = products.filter((product) => product.id !== id);
    setProducts(newProducts);
  };

Enter fullscreen mode Exit fullscreen mode

What we will do next is to pass in handle delete as a prop in both the parent and child components as appropriate. The codes for both pages will go like so;
Home page

import { useState } from "react";
import ProductList from "./ProductList";

const Home = () => {
  const [products, setProducts] = useState([
    { name: "Product 1", description: "lorem 123...", price: 5.45, id: 1 },
    { name: "Product 2", description: "lorem 123...", price: 9.99, id: 2 },
    { name: "Product 3", description: "lorem 123...", price: 20.0, id: 3 },
  ]);
  const handleDelete = (id) => {
    const newProducts = products.filter((product) => product.id !== id);
    setProducts(newProducts);
  };

  return (
    <>
      <div className="home">
        <ProductList
          products={products}
          title="All Products"
          handleDelete={handleDelete}
        />
      </div>

      <div>
      </div>
    </>
  );
};

export default Home;

Enter fullscreen mode Exit fullscreen mode

ProductList component

const ProductList = ({ products, title, handleDelete }) => {
  return (
    <>
      <div className="products">
        <h1>{title}</h1>
        <ul>
          {products.map((product) => (
            <li className="product-list" key={product.id}>
              <h3> {product.name}</h3>
              <p> {product.price}</p>
              <button onClick={() => handleDelete(product.id)}>Delete</button>
            </li>
          ))}
        </ul>
      </div>
    </>
  );
};

export default ProductList;
Enter fullscreen mode Exit fullscreen mode

output

Image description

Clicking on the delete button will remove the particular product from the rendered array. note that the original array is still unmutated. What was rendered here is the newProduct array that we called with setState hook.

Summary

React is a front-end library for building single page applications. Only the index.html file will be sent from the server, while react handles every page loads from the client side. React makes use of reusable components to render content to the DOM. These components contain their own logic and html template that will be exported for use by other parent components.
State in react refers to data that change within the component over time. And in react, we cannot use document.get to interact with the DOM, We also cannot change variable values in hope that react will rerender the new values. Hence we use the useState hook to handle and manage state in the application.
Props are used to make components reusable. To access data from a parent component to child components you have to pass the data as props. We can also pass in functions as props to perform various operations.

Top comments (0)