Components in React serve as the fundamental building blocks of an application. Essentially, a React component returns a JSX element that is rendered in the user interface. Additionally, a component can encompass other features such as state management, properties (props), and lifecycle methods.
React categorizes components into two main types:
- Functional components: These are JavaScript functions that return JSX elements. Initially, they were stateless components, lacking support for managing state. However, with the introduction of React hooks in version 16.8, functional components gained the ability to declare and manage state, transforming them into stateful components.
In the above code, SayHello is a functional component and it is returning a JSX element. In the end, the SayHello function is being exported. Basically, SayHello is nothing but a plain JavaScript function.
- Class components: These are JavaScript classes extended to React.Component. They require a mandatory render() method that returns a JSX element. Historically, React heavily relied on class components because only they supported local state management ("state").
The above class component is the equivalent of the earlier functional component. It is easily observable that the functional component is more easily readable than the class component. Moreover, it is easier to work with functional components because writing class components is more complex and complicated.
Class Component
These are mounting, updating, and unmounting. The lifecycle methods are very useful because sometimes, we may want to execute a piece of code at a specific time. For example, suppose we want to call an API just after the component is mounted. In such a case, we can use the componentDidMount lifecycle method.
Mounting phase with componentDidMount
This is the first stage of a React component’s lifecycle where the component is created and inserted into the DOM.The componentDidMount lifecycle method executes once after initial rendering. If an empty dependency array is provided as the second argument, the callback function executes only after initial rendering.
Analyze variables before loading using the constructor.
1.Constructor (constructor()):The constructor()
method is a special method for initializing state (this.state) and binding event handler methods. In this code, super() is called to invoke the constructor of the parent Component class (from which App extends). Then, this.state is initialized with an object containing count: 0.
2.Component Did Mount (componentDidMount()):componentDidMount()
is a lifecycle method that is called immediately after a component is mounted (i.e., inserted into the DOM tree). In this code, it logs a message to the console indicating that the component has rendered for the first time. This is useful for performing actions that require DOM nodes or initial state setup.
3.Increment Method (increment()):increment()
is a custom method defined within the App class. When called, it updates the component's state using this.setState()
. In React, setState()
is used to update state values asynchronously. Here, it increments the count state by 1 each time the button is clicked.
4.Component Will Unmount (componentWillUnmount()):This lifecycle method is called just before the component is removed from the DOM. It's useful for cleanup activities such as cancelling network requests, removing event listeners, or cleaning up subscriptions. Here, it logs a message indicating that the component is being removed.
5.Render Method (render()):The render()
method is a required method in every React component class. It returns JSX (JavaScript XML) that defines the UI of the component. In this code, it renders a <div>
containing an <h1>
element displaying the current value of this.state.count
and a <button>
element that calls this.increment()
when clicked.
Binding Methods:
•Method 1:Arrow Function in Render Method (onClick={() => { this.increment() }})
:This approach creates a new function instance every time the component renders. While straightforward, this can lead to performance implications, especially in larger applications.
•Method 2:Binding in Constructor (onClick={this.increment.bind(this)})
:
This approach binds this.increment() to the current instance of App in the constructor. It ensures that this refers to the component instance when increment() is called, avoiding the need for creating new function instances on each render.
Lifecycle Summary:
•Mounting Phase:During the mounting phase, React calls the constructor() first, initializing state. Then, render() is called, returning JSX to render the component's UI. Finally, componentDidMount() is invoked after the component is rendered for the first time, where initialization tasks, API calls, or subscriptions can be performed.
•State Management:this.state allows components to manage their own state. Updates to state using this.setState() trigger re-rendering of the component, ensuring UI remains synchronized with data changes.
Updating phase with componentDidUpdate
This updating stage occurs after the component has mounted and rendered into the DOM. A React component updates when there is a change in its props or state. The componentDidUpdate lifecycle method is invoked after the component updates. This method can be used to compare if a specific prop or state has changed.
Component Did Update
(componentDidUpdate(prevProps, prevState))
:
componentDidUpdate() is a lifecycle method invoked immediately after a component updates and after render() is called. It receives two arguments:
o prevProps: Represents the previous props before the update.
o prevState: Represents the previous state before the update.if (prevProps.number !== this.props.number) { console.log("Component Updated"); }
: Compares the current number prop(this.props.number)
with its previous value(prevProps.number)
. If they differ, it logs "Component Updated" to indicate that the component has been updated due to a change in props.
Updating Phase:
• During the updating phase, React compares the previous props and state with the current props and state to determine if the component needs to re-render. componentDidUpdate() is called after this comparison and rendering process.
• It is typically used for operations that need to be performed after a component updates, such as fetching new data based on props changes or interacting with the DOM.
Now, let's see how this can be achieved in a functional component.
The useEffect hook is used to perform side effects in functional components. It takes two arguments: a callback function and a dependency array. The callback function executes based on the presence and values in the dependency array. This is how lifecycle method-like functionality is achieved in functional components.
• Cleanup Function: The function returned from the useEffect hook is the cleanup function. It runs when the component is unmounted or before the effect is re-executed due to dependency changes. Here, it logs "Functional Component: Removed" to the console.
• Dependency Array: The second argument to useEffect is the dependency array. This array specifies the dependencies that the effect depends on. If any value in this array changes, the effect will re-run. In this case, [number] indicates that the effect should re-run whenever the number prop changes.
Lifecycle Summary in the Context of useEffect:
• Mounting Phase: When the Counter1 component is first rendered, useEffect runs and logs "Functional Component: Updating..." to the console.
• Updating Phase: Whenever the number prop changes, useEffect runs again. Before running the effect function, React calls the cleanup function from the previous effect, logging "Functional Component: Removed" and then logs "Functional Component: Updating..." again.
• Unmounting Phase: When the Counter1 component is removed from the DOM, the cleanup function from the last effect run is called, logging "Functional Component: Removed" to the console.
State in functional components
Initially, it was not possible to use state in functional components because the setState() method was only supported in class components. However, with the introduction of React hooks, it is now possible to use state in functional components.
The state of a component in React is a plain JavaScript object that controls the behavior of the component. A change in state triggers a re-render of the component.
There are two main React hooks used to declare and manipulate the state in a functional component:
- useState
- useReducer
The Counter functional component in React uses the useState hook to manage a count state variable. The useState(0) hook initializes count to 0 and provides a setCounter function to update it. The component returns a fragment containing two buttons and an <h2>
element. The first button increments the count by 1, and the second button decrements the count by 1, both using the setCounter function. The current count value is displayed inside the <h2>
element. This demonstrates how to handle state and update it in response to user actions using the useState hook in a functional component.
The useReducer hook is used for complex state management. When the state is interdependent, the useReducer hook is preferred over the useState hook. To understand useReducer, one should know what a reducer is and how to use it.
A reducer is essentially a pure function that takes the current state and an action as arguments and returns a new state.
It is very similar to the useState hook but instead of creating a function to update the state, the useReducer hook creates a function for dispatching actions. The useReducer hook has two arguments - reducer and an initialState. There is a third optional argument for initializing the state lazily.
Top comments (0)