DEV Community

Kim Heidorn
Kim Heidorn

Posted on • Edited on

Troubleshooting? Don't over ReactJS!

For my capstone project at Flatiron School, I decided to build a scaled down version of The Price is Right in React. Simplifying the functionality of the game was essential to complete the project in three weeks. As with any game, logic dominated a majority of the page rendering, and I relied on React Router to dynamically navigate through my various pages. This did not cause any issues until I had a fetch PATCH request in an onClick within a Link. I had a button element wrapped by a Link so I could style it to my satisfaction. Within the button, I passed the fetch request function to the component in props. However, the function required event.preventDefault(). Someone who is more familiar with React Router would have seen the issue with how I had setup my code. I, being a novice, could not understand why the link would not redirect. The fetch PATCH request would complete as would internal console.log(). The issue clearly was with the Link.

After reading the React Router documents, I learned that the event.preventDefault() was preventing the Link from redirecting the user to the correct page. In order to properly redirect and keep the function, I needed to access the session history prop for React Router to redirect the user to the correct route. I was unsure how to do this, but thankfully StackOverflow and this blog by Tyler McGinnis helped direct the correct step to take. Seeing as the redirect was not being rendered by React Router, I had to wrap the component in withRouter to access history.push.

export default withRouter(SpinningWheel )

Once history.push was accessible, I created a callback function within the wrapped component to force the redirect to my desired page.

goHome = () => {
   this.props.history.push('/')
}

So, I had the callback function written, but I needed to hook it up to the fetch request. Calling this callback function beforehand would be useless as the fetch PATCH updated the user’s score upon completion of the game. I only wanted to redirect the user once the score had been saved properly. The fetch function was on my main component page, and thus, I had to pass goHome as a parameter and add a callback function to the fetch request. For brevity, I referenced this as cb in my code.

In withRouter(<Component>):

<Link to="/">
   <button className="Start-button"
      onClick={(ev) => saveMoney({ totalMoney }, ev, this.goHome)}>
      Go Home
   </button>
</Link>

In App.js:

saveMoney = (money, event, cb) => {
   event.preventDefault()

   cb & cb()

   let { gameId } = this.state
   let url = "http://localhost:3000/games/" + gameId

   let config = {
      headers:{
         'Content-Type': 'application/json'
       },
      method: 'PATCH',
      body: JSON.stringify({
         score: money.totalMoney
      }
   }

   fetch(url, config)
      .then(response => response.json())
      .then(data => {() => {
         this.getScores()
         cb & cb()
      })
}

Finally, I can now redirect the user without altering the code too much, and without causing a reload effect for the user, aka using React properly.

Truthfully, this was one of many challenges I had with my React game. My 3D spinning wheel turned out to be my toughest issue, unsurprisingly. Next week, I’ll be writing and sharing my code (and love!) for a vertical carousel. Stay tuned!

Learn more about withRouter and other higher-order components (HOC)

Top comments (0)