Mastering Props and State in Reactjs

All about Props and State..

Why do we need props and a state?

→ In real-time applications, Components must deal with dynamic data.

→ Data could be something internal to a component or maybe passed from another component. So to bind the data to the component, two javascript objects state and props are used.

What is state?

→ State is a JS object used to manage the data of an application.

How do we associate states with components?

→ By using the useState hook.

Syntax:

const[count, setCount] = useState(0);
/*
count is a state variable which is initialized with the value 0.
setCount is the function used to update the state count. 
*/

useState() is a function that takes ‘initialState’ as the initial value for any state variable and returns 2 values.

Note: Whenever the state is updated, the component is re-rendered, and the updated value is displayed on the UI.

Example 1:

import {useState} from 'react';
function Example() {
  const [count,setCount] = useState(0);
  return (
    <div>
      count is: {count}<br/>
      <button onClick={()=>setCount(count + 1)}>Click</butto
    </div>
  );
}
export default Example;

On clicking on the button, the count will be increased by 1 and it will render the same time on the UI.

example 2 with handler:

import {useState} from 'react';
function Example2() {
  const [count,setCount] = useState(0)
    const handleChange = () => {
      setCount(count+1)
    }
  return (
    <div>
      count is: {count}<br/>    
      <button onClick={handleChange}>Click to Increase</button>
    </div>
  );
}
export default App;

This also generates the same output as the previous one, in this there is a minor difference that is we are using a handler to handle the click and change the state value.

Note: useState() can be used to hook any number of times in any component to set multiple state variables.

Why Props?

→ To pass any data from the parent component to the child component, it is passed as a props.

Props (short for “properties”) are a way to pass data from a parent component to a child component in React. → Props are similar to function parameters in JavaScript and can be any type of data (e.g. strings, numbers, objects, functions, etc.).

→ Props are read-only and cannot be modified(immutable) by the child component.

→ Props are used to create reusable and composable components and to share data between different parts of a React application.

How to pass and access props?

→ The props are passed as arguments to functional components and can be accessed within the components.

Example 1:

Parent Component: Employees

  • Employee child component is rendered, and employees state is passed as props.
import {useState} from 'react';
import Employee from './Employee';

// Parent Compnent - Employees
const Employees = () =>{
  const [employees, setEmployees] = useState([
      { empId: 1234, name: 'John', designation: 'SE' },
      { empId: 4567, name: 'Tom', designation: 'SSE' },
      { empId: 8910, name: 'Kevin', designation: 'TA' }
        ])

  return(
     // Sending or Passing props to child component 
    //   <Employee employees={employees} />
    <Employee employees={employees} />
    )
}

export default Employees;

Child component: Employee

  • employees props are accessed within the Employee component to display the employee details.
// Child Component - Employee
// Recieving the props
const Employee = (props) => {
  return (
    <>
      <table>
        <thead>
          <tr>
            <th>EmpID</th>
            <th>Name</th>
            <th>Designation</th>
          </tr>
        </thead>
        <tbody>
          {/* Accessing the props */}
          {props.employees.map((employee) => {
            return (
              <tr key={employee.empId}>
                <td>{employee.empId}</td>
                <td>{employee.name}</td>
                <td>{employee.designation}</td>
              </tr>
            );
          })}
        </tbody>
      </table>
      <br />
      <br />
    </>
  );
};
export default Employee;

Output:

You can destructure the props on the fly like this:

// Recieving the props
const Employee = ({employees}) => {
  return (
    <>
      <table>
        <thead>
          <tr>
            <th>EmpID</th>
            <th>Name</th>
            <th>Designation</th>
          </tr>
        </thead>
        <tbody>
          {/* Accessing the props */}
          {employees.map((employee) => {
            return (
              <tr key={employee.empId}>
                <td>{employee.empId}</td>
                <td>{employee.name}</td>
                <td>{employee.designation}</td>
              </tr>
            );
          })}
        </tbody>
      </table>
      <br />
      <br />
    </>
  );
};
export default Employee;

Note:

1. Props are immutable **The child component cannot modify the props. However, when parent component updates the data that is passed as props then the Child component gets updated props.

2. Whenever props are updated the component gets re-rendered and displays the latest value in the UI.

Q. One Question would arise inside your mind, Is there any way to do Child to Parent Communication?

→ The Answer is Yes. It is possible to pass data from the child to the parent component.

→ It can be done by invoking a function that is passed as props from the parent component.

Example:

import {useState} from 'react';
import Employee from './Employee';

// Parent Compnent - Employees
const Employees = () =>{
  const [employees, setEmployees] = useState([
      { empId: 1234, name: 'John', designation: 'SE' },
      { empId: 4567, name: 'Tom', designation: 'SSE' },
      { empId: 8910, name: 'Kevin', designation: 'TA' }
        ])


    const addEmployee = () => {
        setEmployees([...employees, { empId: 6789, name: "Clara", designation: "TL" }]);
        };
        return(
            // Sending or Passing props to child component 
           //   addEmployee is props
           <Employee employees={employees} addEmployee={addEmployee} />
           )

}


export default Employees;

In the parent component, there is a function called addEmployee, I am sending it child component as props so the Child component can use it and make changes to the state variable.

// Child Component - Employee
// Recieving the props
const Employee = (props) => {
  return (
    <>
      <table>
        <thead>
          <tr>
            <th>EmpID</th>
            <th>Name</th>
            <th>Designation</th>
          </tr>
        </thead>
        <tbody>
          {/* Accessing the props */}
          {props.employees.map((employee) => {
            return (
              <tr key={employee.empId}>
                <td>{employee.empId}</td>
                <td>{employee.name}</td>
                <td>{employee.designation}</td>
              </tr>
            );
          })}
        </tbody>
      </table>
      <br />
      <br />
          {/* Clicking button on Child component, It is communcating to parent and making change in state variable employees */}
      <button onClick={props.addEmployee} style={{border:"1px solid grey", backgroundColor:"skyblue"}}>
        Add an Employee
      </button>
    </>
  );
};
export default Employee;

Output:

After clicking on the Add an Employee button:

  • The addEmployee method is invoked when the button is clicked.

thanks..