skip to Main Content

I have a logout button in header which only changes its state once on click from login to logout. So the total no. of renders should be 2

  1. when app loads
  2. on first click of login button which changes to text from login to logout
    but an additional render is happening after this when I click logout button again though text has not changed. Based on react core concept of diff algorithm this re render without any text change should have not happend.
    Can anyone help me out to explain why this additional render happening?
    Link to code : https://playcode.io/1688044
import { useState } from 'react';
// import { useState, useEffect } from 'react';
import { LOGO_URL } from '../utils/constants';

const Header = () => {
  const [btnName, setBtnName] = useState('Login');
  console.log('Header rendered');
  return (
    <div className='header'>
      <div className='logo-container'>
        <img className='logo' src={LOGO_URL} />
      </div>
      <div className='nav-items'>
        <ul>
          <li>Home</li>
          <li>About us</li>
          <li>Contact</li>
          <li>Cart</li>
          <button
            className='login-btn'
            onClick={() => {
              setBtnName('Logout');
            }}
          >
            {btnName}
          </button>
        </ul>
      </div>
    </div>
  );
};
export default Header

I was expecting the component to render only twice

  1. Initial render
  2. On click of button first time since it changes from Login to Logout

But it is rendering one more time when I click on button though text remains the same as Logout

2

Answers


  1. This is a feature of React where it does an extra re-render before deciding to ‘bail out’ which means stop rendering child components. This is because there may be an inline reducer which may still be running and so this extra re-render is just to make sure that it is safe to bailout.

    This was extensively discussed here. You can read about reducers here.

    Login or Signup to reply.
  2. After applying this it will not render one more time when You click on button but text remains the same as Logout

    import React, { useState, memo } from 'react';
    
    const Header = () => {
      const [btnName, setBtnName] = useState('Login');
      console.log('Header rendered');
    
      return (
        <div className='header'>
     <div className='logo-container'>
          </div>
          <div className='nav-items'>
             <ul>
             <li>Home</li>
             <li>About us</li>
              <li>Contact</li>
              <li>Cart</li>
          <button
            className='login-btn'
            onClick={() => {
              if (btnName !== 'Logout') {
                setBtnName('Logout');
              }
            }}
          >
            {btnName}
          </button>
            </ul>
          </div>
        </div>
      );
    };
    
    export default memo(Header);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search