Home > Software engineering >  react component displaying in first render but not in the following re-render
react component displaying in first render but not in the following re-render

Time:07-17

I have a react component that consists in an alert to which i am passing 2 props.

const AlertPopUp= ({severity, errors}) =>{
const [show, setShow] = useState(true)
console.log('show value of show state: ', show)
useEffect(() => {
  console.log('gets here')
  const timeId = setTimeout(() => {
    // After 5 seconds set the show value to false
    setShow(false)
  }, 5000)

  return () => {
    clearTimeout(timeId)
  }
});
console.log('errors ', errors)
if (!errors)  return null
if (show) 
return (
    <>
    <Alert severity = {severity}>
      {errors}
    </Alert>
  </>)}

In the first render, the alert shows up and after the expected 5 seconds the component dissapears.

In the re-render, the alert does not show up anymore, from my debugging i assume it has to do to with the line console.log('show value of show state: ', show) which displays false in the re-render.

If i do a setShow(true) i run into a infinite loop of re-renders.

If i use a useRef to avoid the useState infinite loop the component doesnt re-render and therefore the alert never shows up.

Please forgive me if i made any of my assumptions wrongly as i am far from being a react expert.

Could please anyone help me find a solution so that the alert displays in every render of the alert component and dissapears after the 5 seconds?

CodePudding user response:

This happens because you are never setting show back to true

CodePudding user response:

Try setting show back to true inside the return statement in useEffect

CodePudding user response:

One solution is to use a different key every time you want to show the component again. This way when you pass a different key when you want the alert to reappear, its old instance will be destroyed, and it will be like rendering that component from the beginning; so the show flag won't be false anymore, which prevents it from appearing in your original case. Here is example:

let Alert = (props) => {
  let [show, setShow] = React.useState(true);

  React.useEffect(() => {
    setTimeout(() => {
      setShow(false);
    }, 5000);
  }, []); // note empty array also

  if (!show) return null;
  return <div>alert</div>;
};
export default function App() {
  let [id, setId] = React.useState(0);
  return (
    <div onClick={() => setId(id   1)}>
      Click to show alert
      <Alert key={id} />
    </div>
  );
}
  • Related