React Component
Rendering
Rendering is to render the React element we created in the browser using ReactDOM.
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.
What is JSX
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.
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 onin 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 usingsetData
. -
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
};
}, []);
Props
In React, props
(short for properties) are a way to pass data from a parent component to a child component. They are a mechanism for communication between components and enable the building of flexible and reusable React applications.
Syntax
When a component is defined, you can specify a list of properties it accepts by using the props
keyword in the function parameters
// Functional component with props
function MyComponent(props) {
// Accessing props in a functional component
return (
<div>
<p>{props.name}</p>
</div>
);
}
The function component takes props as one argument (parameter names are commonly used as props, but other names can be used)
How to use Props
1. Passing props from Parent to Child:
In the parent component, when rendering the child component, you can pass values as attributes.
// Parent component
import React from 'react';
import ChildComponent from './ChildComponent';
function ParentComponent() {
return <ChildComponent name="John" />;
}
2. Accessing Props in the Child Component:
In the child component, you can access the passed values through the props
object.
// Child component
import React from 'react';
function ChildComponent(props) {
return (
<div>
<p>{props.name}</p>
</div>
);
}
3. Props are Read-Only
In React, props are read-only. A child component should not modify the values received through props. They are intended for one-way communication from parent to child.
Example
// Parent component
import React from 'react';
import ChildComponent from './ChildComponent';
function ParentComponent() {
return <ChildComponent name="John" />;
}
// Child component
import React from 'react';
function ChildComponent(props) {
return (
<div>
<p>{props.name}</p>
</div>
);
}
In this example, ParentComponent
renders ChildComponent
and passes the name
prop with the value "John". The ChildComponent
receives and displays the value of the name
prop.