1

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.

4
  • 1
    just add some more state indicating if they user has clicked existing or create your own and then render the different html based off that? Commented Jun 17, 2020 at 10:49
  • I suppose this behaviour is because of window.onload. I tried not to use it but then not having it an error saying "cannot read property 'addEventListener' of null". That is why I am using window.onload. Commented Jun 17, 2020 at 10:55
  • 1
    you shouldn't need to use anything like that: window.onload=function(){ you can call a function inside useEffect and it'll be called onload Commented Jun 17, 2020 at 10:56
  • @RedBaron Thank you! It nearly solved the problem! But after quitting the development server and starting again, <div>Form</div> appeared, not the <Modal/>. This is another reason I feel induced to use window.onload. Commented Jun 17, 2020 at 11:07

1 Answer 1

1

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]);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.