4 Things I Wish I Had Known Before Writing my First React App
Like many developers, I immediately fell in love with React. I found it to be clean and intuitive, and with the addition of other libraries (such as React Router and Redux), full of possibility to act as a full-fledged frontend framework. However, I was far less enamored with my own React code. With some more study (plus some tips from our resident JavaScript expert, Rafał), I found that there were solutions to many of the pain points that I had experienced. So, with the benefit of hindsight, here are the top four things I wish I had known when writing my first React App:
1) The React CLI is a thing of beauty.
Writing a React App is fun, but just getting up and running used to require a substantial amount of not-so-fun configuration. If you’re not familiar with NPM (or Yarn) and Webpack, that initial configuration can be daunting.
React has since blessed developers with an easy-to-use CLI, where you can get up and running in just a few commands. If you later find the CLI’s magic to be constrictive, you can run the ‘eject’ command. Ejecting moves your main package.json file out of the react-scripts folder and into its usual location in your root directory. You are then free from the CLI while continuing to take advantage of those initial automated configurations.
2) Do I need Flux or Redux? Am I making a big mistake if I don’t use one?
The Flux pattern, and its most well-known implementation, Redux, is a common store for state that can be accessed across components. As you probably know, data in React flows downwards. When a child component needs to inform a parent component about a change, it does so by invoking a callback that you passed to the child from the parent. The parent then changes its own state. So, while some information about state is passed back upstream, the actual state is never set from the bottom-up.
Without Redux, I found myself having to place these callback functions at the highest common ancestor of two components, and then passing the event handler down (often through multiple child components). Essentially I was home-rolling my own state-management, and it got messy fast.
An easy rule of thumb: do you have a component that is going to need to know the state of another component that is not its direct parent? If so, you’ll probably need Redux. Luckily, you don’t necessarily need to integrate Redux from the very start of the project. When you get to the point of realizing that you need it, you probably won’t be so far along that it will be difficult to add.
3) Take full advantage of ES6.
React applications almost always use Babel to transpile JSX to regular old JavaScript. An added bonus of working with Babel is that it can convert ES6 code to ES5, making it cross-browser friendly.
ES6 features make JavaScript easier to write, and a few features are particularly useful when writing React:
ES6 imports: You can break your components into separate files without needing to use require(). To import a component into another component, you only need to indicate where to import from, e.g: import SideMenu from './Nav/SideMenu'
.
‘Destructuring’ makes it easier to extract values from objects and arrays. In React code, you can use this to avoid repeatedly typing ‘this.props’. For example, if your component is receiving the properties ‘profile’ and ‘purchases’, you can restructure these properties at the top of your component by writing:
const { profile, purchases } = this.props
Then in your component you can reference ‘profile’ and ‘purchases’, instead of the more cumbersome this.props.purchases
or this.props.profile.age
.
Spread operator: Data can be passed more succinctly using the spread operator. For example, If you have an object ‘profile’ with multiple properties, you can pass all of those properties from ComponentA to ComponentB using . When accessing that information in ComponentB, you can then reference the properties of the profile object directly (e.g. this.props.name
rather than this.props.profile.name
).
4) propTypes for code readability
When looking at a component, it isn’t readily apparent what properties that component is expecting to receive in order to run properly. When writing my first React App, I batted down property errors galore.
You could add comments to indicate which properties are required, but listing expected properties using React.PropTypes will provide the same clarity while also reducing the possibility of errors by adding type checking.
For example, if your top navigation bar is expecting a user name and a photo, you could write: static propTypes = {name: React.PropTypes.string.isRequired}
Then if you run this component without the required properties, you will see an error in the console:
Warning: Failed prop type: The prop 'name' is marked as required in 'Nav', but its value is 'undefined'.
So, while totally optional, propTypes are an easy way to improve code readability and maintainability.
Happy React-ing!