Search code examples
reactjsuse-effect

Component is not rendered using useEffects


I have few Checkboxes in component of React application, but whenever I'm checking they are not working as they should work!

Whenever I click on any Checkbox from ColumnCheckBoxes Component it is getting appended in selectedColumns but selectedColumns are not displayed using DuplicateCheckBoxes component.

selectedColumn & duplicateColumn are states which is in useEffect so as soon as they change whole page needs to get re-rendered.

In backend I want to pass list of selectedColumn as well duplicateColumn(unique property will be applied to column while inserting data into SQL)
App.js

import { useEffect, useState } from 'react';
import ColumnCheckBoxes from './Components/CheckBoxes/ColumnCheckBoxes';
import DuplicateCheckBoxes from './Components/CheckBoxes/DuplicateCheckBoxes';

const App = () => {

  const [columns,setColumns]=useState([]);
  const [selectedColumn,setSelectedColumn] = useState([]);
  const [duplicateColumn, setDuplicateColumn]=useState([]);

  // componentDidMount
  useEffect(() => {
    console.log('Initial Rendering!');
    setColumns(['A','B','C','D']);
  },[]);

  // componentDidUpdate
  useEffect(() => {
    console.log('Selected Column',selectedColumn);
    console.log('Duplicate Columns',duplicateColumn);
  },[selectedColumn,duplicateColumn]);

  return (
    <div className='flex-col justify-center align-middle'>
      <div><ColumnCheckBoxes columns={columns} selectedColumn={selectedColumn} setSelectedColumn={setSelectedColumn}/></div>
      <div><DuplicateCheckBoxes selectedColumn={selectedColumn} duplicateColumn={duplicateColumn} setDuplicateColumn={setDuplicateColumn}/></div>
    </div>
  );
}

export default App;

ColumnCheckBoxes

import React from 'react'

const ColumnCheckBoxes = ({columns, selectedColumn, setSelectedColumn}) => {

    const handleChange = (event,header) => {
        event.preventDefault();
        if(!(event.target.checked)) return;
        const localarr = selectedColumn;
        localarr.push(header.header);
        setSelectedColumn(localarr);
    }

  return (
    <div className='flex flex-col justify-center align-middle'>
        <h1>Columns :</h1>
        {columns.map ((header) => {
            return <div key={0} className='flex'>
                <label className='ml-2'>{header}</label>
                <input type='checkbox' className='ml-2' 
                    checked={header.header in selectedColumn?true:false} 
                    onChange={(e) => handleChange(e,{header})}
                />
            </div>
        })}
    </div>
  )
}

export default ColumnCheckBoxes;

DuplicateCheckBoxes

import React from 'react';

const DuplicateCheckBoxes = ({selectedColumn, duplicateColumn, setDuplicateColumn}) => {

    const handleChange = (event,header) => {
        event.preventDefault();
        if(!(event.target.checked)) return;
        const localarr = duplicateColumn;
        localarr.push(header.header);
        setDuplicateColumn(localarr);
    }

  return (
        <div className='flex flex-col justify-center align-middle'>
            {selectedColumn.length === 0 ? <div></div> : <h1>Remove Duplicate Elements From Column</h1>}
            {selectedColumn.map ((header) => {
                return <div key={0} className='flex'>
                    <label>{header}</label>
                    <input type='checkbox' className='ml-2' onChange={(e) => handleChange(e,{header})}/>
                </div>
            })}
        </div>
  )
}

export default DuplicateCheckBoxes;

Solution

  • Instead of

    const localarr = selectedColumn;
    localarr.push(header.header);
    setSelectedColumn(localarr);
    

    do this

    setSelectedColumn(columns => [...columns,header.header])
    

    localarr is reference to selectedColumn or duplicateColumn so I was trying to change State without state changing method!😁