user36339
user36339

Reputation: 273

Problem with useEffect() on loading the page

I am having trouble with my react quiz app. Here follows the description: This is from App.js file:

...
const [createQuiz, setCreateQuiz] = useState(false);
...
useEffect(()=> {
    const reRender = () => {
        setCreateQuiz(true)
    }
    window.onload=function(){
      document.getElementById("myBtn").addEventListener("click", reRender);
    } 
    // return document.getElementById("myBtn").removeEventListener("click", reRender);
  }, [createQuiz])

return (
    <QuizContextProvider>
      {
      (createQuiz) ? (
        <div>Form</div>
      ) : (
        <div>
        <Modal/>
        <Question question={questions[questionNumber]} next={goToTheNext} />
        </div>
      )
      }
      {console.log(createQuiz)}
    </QuizContextProvider>
  );
}

As can be seen it is a conditional rendering: a Modal window asks a user whether they want to take the existing quiz or create their own and when the user clicks "Create your own " button, the app should re-render over again, this time the useEffect() (in App.js) sets the value of createQuiz to true. the code excerpt below is from <Modal /> component:

return (
        <div className='benclosing' style={{display:displayValue}}>
        <div className='modal'>
            <h1>Welcome!</h1>
            <p>Do you want to take an existing quiz or create your own?</p>
            <button onClick={hideWindow} >Existing quiz</button>
            <button id='myBtn'>Create your own</button>
        </div>
        </div>
    )
}

Everthing works fine as expected, except for 1: whenever reload icon is clicked, my page re-renders over-again and the user is again asked if they want to take the existing quiz. I want that refreshing affect nothing. I am stuck with this problem. How can I achieve the desired result?

I also tried this:

  const reRender = () => {
    setCreateQuiz(true)
  }

  useEffect(()=> {
    reRender()
    //return setCreateQuiz(false)

  }, [createQuiz])

It didn't work as expected. I described what it caused in my 2nd comment to Red Baron, please have a look.

Upvotes: 1

Views: 5106

Answers (1)

goto
goto

Reputation: 4435

The proper way to achieve what you want is to create an event handler inside your App component that will set createQuiz to true when the Create your own button gets clicked inside the Modal component.


function App() {
  const [createQuiz, setCreateQuiz] = React.useState(false);

  const handleShowQuizForm = () => {
    setCreateQuiz(true);
  };

  return (
    <div>
      {createQuiz ? (
        <div>Form</div>
      ) : (
        <>
          <Modal showQuizForm={handleShowQuizForm} />
        </>
      )}
    </div>
  );
}

function Modal(props) {
  return (
    <div>
      <button type="button" onClick={props.showQuizForm}>
        Create your own
      </button>
    </div>
  );
}

Here's an example:

There's no need for the useEffect hook here and the window.onload event implies to me that you'd want to set createQuiz to true then "refresh" your page and expect createQuiz to now be true - it won't work like that.

Additionally, the way you're using the useEffect hook could be problematic - you should try to stay away from updating a piece of state inside of a useEffect hook that's also part of the dependency array:

React.useEffect(() => {
  const reRender = () => {
    setCreateQuiz(true);
  }
  // although not an issue here, but if this hook was
  // rewritten and looked like the following, it would
  // case an infinite re-render and eventually crash your app
  setCreateQuiz(!createQuiz);
}, [createQuiz]);

Upvotes: 1

Related Questions