Troubleshooting? Don't over ReactJS!
Kim Heidorn
Posted on June 8, 2019
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)
Posted on June 8, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.