Skip to main content

React Component

 

Rendering 

Rendering is to render the React element we created in the browser using ReactDOM.

image.png

 


Re-rendering 

Happens when a rendered React element has a props or state that has changed from the previous render. That React element will be rendered again with a new set of props and state values.

image.png

 


What is JSX 

image.png

As an extension of JavaScript, we can create elements by writing HTML tags, and can also use JavaScript's capabilities to perform logic. JSX formally is a JavaScript extension that allows creation of DOM trees using an XML-like syntax.

image.png

 


React Component 

Components allow us to break down the user interface into smaller, self-organizing parts. and we can reuse it
There are two types of components in React:

1. Class Component 

Class components are ES6 classes that extend from React.Component.  They have a render method that returns the component's JSX (what should be rendered on the UI).

Below is original way of coding react, which later has react hooks, so function components can be written as class components as well 

class Hello extends React.Component{
    render() {
        return (
        <h1>Hello World</h1>
        );
    }
}
ReactDOM.render(<Hello />, document.getElementById('root'));
2. Function Component 

it is a component written with a function that must return a value as a React element that will be rendered by React.
Function components are simpler and more concise than class components. They are just JavaScript functions that take props as an argument and return React elements. 

function Hello(){
    return <h1>Hello World</h1>
}
export default Hello;



Export / Import 

In React (and JavaScript in general), the export and import statements are used to organize and share code between different files or modules. We call JavaScript files with export/import Module

There are 2 types of commonly used forms:

1. Named export/import 
  • You can export functions, variables, or classes by using the export keyword followed by the name of the entity you want to export. 
  • When importing named exports, you use curly braces {} to specify the names of the entities you want to import.
//file1.js
export const name = "John";
export const age = 25;
//file2.js
import { name, age } from "./file1.js";

 

2.  Default export/import
  • You can also export a default entity from a module using the export default syntax. There can only be one default export per module.
  • When importing the default export, you don't need curly braces. You can use any name you want for the default import.
//file1.js
const name = "John";
export default name;
//file2.js
import AnyName from "./file1.js";

 


State

State is a variable that stores data inside a component, similar to props, but using props, the data cannot be changed, but the state can. During app execution, it uses State, which is the original format written internally. The state represents the current condition or values of a component and determines how it should render. State enables components to be dynamic and responsive to user interactions.

 

Hooks

Hooks are functions that enable functional components to use state, lifecycle methods, context, and other React features that were previously only available in class components.  Hook, for calls to add state or other React capabilities to function components

There are 2 hooks that we will often see: 

1. useState 

Used to declare state variables to function component. In 1 component, you can declare as many times as you like.
The values of state variables are stored with React

How to use?
  • It must only be called within a function component. 
    Hooks are designed to be used within functional components or custom hooks. They should not be called in regular JavaScript functions or outside the scope of a component.
    // Correct: useState is called within a function component
    function MyComponent() {
      const [count, setCount] = useState(0);
      // ...
    }
    // Incorrect: useState is called outside a function component
    const [count, setCount] = useState(0);
    

  • Must be called at the top of the function component 
    Hooks must be called at the top level of a function component, meaning they should appear at the beginning of the component's body, before any conditional statements, loops, or nested functions
    // Correct: useState is called at the top of the function component
    function MyComponent() {
      const [count, setCount] = useState(0);
      // ...
      if (someCondition) {
        // ...
      }
      return <div>{/* ... */}</div>;
    }
    
    // Incorrect: useState is not at the top level
    function MyComponent() {
      if (someCondition) {
        const [count, setCount] = useState(0); // Incorrect
        // ...
      }
      return <div>{/* ... */}</div>;
    }
    

  • The call order must be the same for every render (not in a condition or a loop). 

Same Order on Every Render:  When you use the useState hook, React relies on the order of hook calls to associate the state variables with their respective values between renders. This means that the order in which you declare your state variables using useState should remain consistent across renders.

// Correct: Same order in every render
const [count, setCount] = useState(0);
const [name, setName] = useState("John");

// Incorrect: Changing order in subsequent renders
const [name, setName] = useState("John");
const [count, setCount] = useState(0);

Not in Conditions or Loops: Hooks should not be called conditionally or within loops. This is because React relies on the call order of hooks to maintain the correct state between renders. If hooks are called conditionally or within loops, the order of calls might vary, leading to unexpected behavior and bugs.

// Correct: useState is called unconditionally at the top level
if (condition) {
  const [count, setCount] = useState(0);
}

// Incorrect: useState is called conditionally
const [count, setCount] = condition ? useState(0) : [0, () => {}];



Example of How useState works

//syntax 
const [state, setState] = useState(initialValue);
  • state: The current state value.
  • setState: A function that is used to update the state.? 

Arguments

The useState function takes one argument, which is the initial value of the state. This initial value can be of any data type: primitive types (number, string, boolean), objects, arrays, etc.

Code Example

import React, { useState } from 'react';

function Counter() {
  // Using a number as the initial state value
  const [count, setCount] = useState(0);

  // ...

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

export default Counter;

In this example, useState(0) sets the initial state value of count to 0. The setCount function is then used to update the state when the "Increment" button is clicked.

Returning Values

1. Current State (state):

  • The first element in the array returned by useState is the current state value (state).
  • You use this value to access the current state of the component. 
const [count, setCount] = useState(0);
// 'count' is the current state value

2. State Update Function (setState):

  • The second element in the array is a function (setState) that is used to update the state.
  • This function can be called with a new value, or a function that receives the previous state and returns a new state
const [count, setCount] = useState(0);
// 'setCount' is a function to update the state
// It can be called like setCount(1) or setCount(prevCount => prevCount + 1)



2. useEffect 

  • Allows you to perform side effects in your functional components, such as data fetching, subscriptions, or manual DOM manipulations.
  • It runs after each render and can clean up resources on component unmount.


How to Use?
  • It must only be called within a function component
  • Must be called at the top of the function component 
  • The call order must be the same for every render (not in a condition or loop)

The value that useEffect can take
  • [Required] effect (function to run after render) 
  • [Optional] dependency array 

The effect will only be executed after rendering is complete

 

Syntax of useEffect
useEffect(() => {
  // Side effect code goes here
  // This function will be called after each render

  return () => {
    // Cleanup code (optional)
    // This function will be called before the component unmounts
  };
}, [dependencyArray]);
  • The first argument to useEffect is a function that contains the code for the side effect.

  • The second argument is an optional dependency array. If provided, it specifies the values that, when changed, will trigger the re-execution of the effect. If no dependency array is provided, the effect runs after every render.

  • The function returned from useEffect is an optional cleanup function. It is called before the component unmounts and before the effect runs again (if dependencies change).

Example of useEffect
import React, { useState, useEffect } from 'react';
function ExampleComponent() {
  const [data, setData] = useState(null);
  useEffect(() => {
    // Side effect code (e.g., data fetching)
    const fetchData = async () => {
      try {
        const response = await fetch('https://api.example.com/data');
        const result = await response.json();
        setData(result);
      } catch (error) {
        console.error('Error fetching data:', error);
      }
    };
    fetchData();
    // Cleanup code (optional)
    return () => {
      // Cleanup code (e.g., cancel subscriptions, clear timers)
    };
  }, [/* dependencyArray */]);
  // Component rendering...
}

In this example:

  • The useEffect hook is used to fetch data from an API after the component renders.

  • The fetchData function is the side effect code. It is an asynchronous function that fetches data and updates the state using setData.

  • The dependency array ([] in this case) is empty, meaning the effect will run after the initial render only. If you have dependencies that should trigger the effect when they change, you would include them in the dependency array.

  • The cleanup function (returned from useEffect) is used for cleanup activities. In this example, it's not doing anything specific, but you might use it to cancel subscriptions, clear timers, or perform other cleanup tasks.


When useEffect will run?

Here are the scenarios in which useEffect will run:

1. After initial Render

If you provide an empty dependency array ([]) as the second argument to useEffect, the effect will run after the initial render of the component.

useEffect(() => {
  // This effect runs after the initial render
  // ...
}, []); // Empty dependency array

2. After Every Render (No Dependency Array)

If you omit the dependency array, the effect will run after every render of the component.

useEffect(() => {
  // This effect runs after every render
  // ...
});

3. When Dependencies Change:

If you provide a non-empty dependency array, the effect will run whenever any of the dependencies change between renders.

const someValue = // ...;
useEffect(() => {
  // This effect runs when 'someValue' changes
  // ...
}, [someValue]);

If there are multiple dependencies, the effect will run when any of them change.

const [count, setCount] = useState(0);
const someValue = // ...;

useEffect(() => {
  // This effect runs when 'count' or 'someValue' changes
  // ...
}, [count, someValue]);

4. Cleanup and Unmount

If a cleanup function is provided (via the return statement inside useEffect), it will run before the next render (if dependencies change) or before the component is unmounted.

useEffect(() => {
  // This effect runs after the initial render

  return () => {
    // Cleanup code runs before the next render or unmount
  };
}, []);