React on Rails, what could go wrong?

Just kidding, it wasn’t really that bad.  Everything I did can be broken down into the following phases:

  • Building the API
  • Building the React
  • Implementing Redux
  • Routing with react-router
  • Styling with react-bootstrap and react-router-bootstrap

Building the API

Easy! The Rails all came back like riding a bike, more or less. Had to do some googling to get syntax right, but by and large putting together a standalone API where I could see the JSON rendered at the routes I wanted it at was a breeze. For the most part, the problems I had were ActiveRecord stuff where the pluralization and capitalization conventions got away from me.

Much harder was linking up the front end to the API. I wanted to do some ‘fake’ authentication where I just kept a single sessions object alive in the database that told the app which user was logged in, and that ended up being a pain. I got it done, but it was hacky. It never fails to surprise me how much the restful actions in a controller can end up doing things that don’t line up at all with what they’re called.

A big hurdle was the fact that when people build Rails apps, they nearly always use form helpers that have a specific way of interacting with controllers. Since I was using JS, I had to understand exactly what kind of information a controller action expects to receive from a form in order to make it available in a ‘params’ object.

Building the React

My biggest trouble with the actual React was knowing how to structure my application, and I think that’s something that I’ll learn more about as time goes on. For example, for a brief moment I wanted to give my users profile pictures, but it was difficult to know where to store them. Should they even belong in the client directory? Seems like that would go in the Rails app/assets folder. Oh, but clients/src files won’t let you import files from outside of src?  A lot of things that seem pretty basic for an app are turning out to be harder than I thought, but I guess that can be said for most frameworks.

Implementing Redux

Definitely the most mind-stretching part of the project, and of learning React in general. I feel like I got a much better handle on the elements of Redux; it’s definitely nice to know that all the info lives in one spot. But then again, couldn’t that responsibility belong to the API? I felt a bit like the store was just working as a middleman between my front-end and my API in this project. Maybe that would be less the case in a situation where the API is just a resource, and doesn’t get mutated by the user’s interactions with the app.

Using fetch() correctly was probably the most difficult part of the entire project. It took me forever to understand that you can’t really return a vlue from a promise chain, you can only call a function in the final .then( ) call on the resolved promise from the second-to-last .then( ). That helped a lot, because I had some situations where I wanted to post info directly to the database instead of messing with state through dispatch( ).

Routing with react-router

After fetch( ), react-router was probably my biggest challenge. The biggest lesson that I learned in using it is that if you’re going to use react-router, EVERY component has to be nested in a Route. Otherwise, when you’re working in that component, you end up realizing that you want a link to take you somewhere, but you’re unable to do a this.props.history.push because props was never passed a  history object.  I ended up in a few situations where I ended up just using an anchor tag and an href because it seemed easier than going through the trouble of doing react-routes just for that one little component, but when most of your links use react-router, suddenly a full dom re-render feels much clunkier and more noticeable.  Doing react-router routes in all of my components is definitely something I’m going to have to accept as a fact of life from now on!

Styling with React-Bootstrap and React-Router-Bootstrap

I never got into bootstrap quite as deeply as I should have, but now I’m all about it! Things are a bit trickier than they were last time I learned about it, though; now I’m using bootstrap! react-bootstrap is a damn cool package with a what I think is a really cool, mutant logo. Pretty much everything that’s available in vanilla Bootstrap is available in the React version, with nearly documentation that looks exactly the same and everything. It was a little difficult adding custom css though, because I couldn’t find the downloadable files and had to use the CDN, so it was hard to know exactly what the css that I was overwriting looked like. Using the react-bootstrap grid system was something I couldn’t figure out either, so I left that for another day. I can’t wait, though. I want to make some components that actually LOOK like components.

One thing that creates problems, though, is that React-Bootstrap doesn’t make itself available as simple classes, but as finished, import-able components that you then give children to. Which is fine until you realize that React-Router works the exact same way. So now you’re trying to wrap a Route around a nav, but you want that nav to be a bootstrap nav, so what wraps around what? Spoiler: neither way works. Enter React-Router-Bootstrap! It gives you more or less nothing but a <LinkContainer> component, which is a bootstrap-friendly version of react-router’s  `<Navlink>` component.  We still need other react-router stuff though, so we have to hang on to that one!

Conclusion

I’m guessing that all this stuff will eventually get wrapped into React native, but it’s fun to see it in this phase, where everything still has to be cobbled together from five different sources. It’s certainly been interesting, and I’m looking forward to doing more with React.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s