Why in ReactJs I can rerender child using useEffect() if the child has been statically generated, but not if it's dynamic

Viewed 129

I have a parent component:

import Button from 'react-bootstrap/Button'
import React, {useState, useEffect} from 'react';

import Counter from './Counter'



function App() {
  const [disabledButton, setdisabledButton] = useState(false);
  const [count, setCount] = useState(2);
  function disableButtonClicked() {
    return disabledButton ? "YES" : "NO";
  } 
    const [buttonList, setButtonList] = useState(
        [<Counter disableButtonClicked={disableButtonClicked} /> ,
          <Counter disableButtonClicked={disableButtonClicked} />]
  );
  const addButton = event => {
    setCount(count + 1);
    setButtonList(buttonList.concat(<Counter disableButtonClicked={disableButtonClicked} />))
}
  return (
      <>
          {/* Statically added component. I can disable the button */}
        <Counter step={ 5 } disableButtonClicked={disableButtonClicked}/>
        <Counter  disableButtonClicked={disableButtonClicked} />
          {/* Dinamically added component I can't disable the button*/}
        {buttonList.map((button)=> (<>{button}</>))}
        <form>
            <label htmlFor="qct-q1-type-multi">Disable button</label>
            <input
                name="darkMode"
                type="checkbox"
                checked={disabledButton}
                onChange={() => setdisabledButton((prev) => !prev)}
            />
            <Button variant="primary" onClick={addButton} size="md" disabled={false}>Add button</Button>
        </form>
    </>
  );
}


export default App;

And here is the Child component:

import React, { useState, useEffect} from 'react'
import './Counter.css'
import { Button } from 'reactstrap';


function Counter({step = 1, disableButtonClicked}) {
    const [count, setCount] = useState(0);
    const [isDisabled, setIsDisabled] = useState(false);
    useEffect(() => {
        console.log(`useEffect ${disableButtonClicked()}`);
        setIsDisabled(!isDisabled)
      }, [disableButtonClicked]);
    return (

        <div className='counterClass'>
            <h2>
                {count}
            </h2>
            <Button className="btn btn-warning btn-xs" onClick={() => setCount(count + step)} disabled={isDisabled}>+++  {step}  +++</Button>
        </div>
    )
}

export default Counter;

There as you see I am creating some child component <Counter/> in which I am passing a function disableButtonClicked() as property. I want that each time the checkbox is checked, then the button inside the Counter is disabled.

Then I would like to be able to generate a dynamic number of Counters. I had managed this by creating a button that will add one <Counter/> to an array each time that is clicked and then it will be added to the return statement via mapping.

Problem is that if I do this, for some reason, the useEffect on counter doesn't get triggered.

Can anybody explain me why this happen? And how can this be solved?

0 Answers
Related