Original text: blog.risingstack.com/react-js-be…

By Peter Marton

React has been a hot topic in recent months, and we believe that more and more developers are experimenting with such a technology. Our team is also learning from our experience on PC and mobile. React is coming of age in 2016. Whether you’re new to React or already familiar with it, it’s time to take a look at some of the best practices

= = = = = = = = = = = = = = = = = = = = = = = = the line = = = = = = = = = = = = = = = = = = = = = = = = = = =

2015 has been the year of React, with releases and developer conferences all over the world. For more on last year’s React milestones, check out our review of React 2015.

Perhaps the most interesting question of 2016 is, how do we write an application, and what are the recommended libraries or frameworks?

As a developer who has been using React. Js for a long time, I already have my own answers and best practices, but you may not agree with everything I say. I am very interested in your thoughts and opinions, please comment in the comments.

If you’re just new to React. Js, read the React. Js tutorial, or Pete Hunt’s React Howto.

The data processing

Working with data in a React. Js application is super simple, but also challenging.

This is because there are several ways you can pass property data to a React component to build a render tree. But this way it’s not always obvious that you should update certain views.

As 2015 begins to see the emergence of a number of Flux libraries with more powerful features and responsive solutions, let’s take a look:

Flux

In our experience, Flux is often overused (that is, people use it when they don’t need it).

Flux provides a clean way to store and manage application state and trigger rendering when needed.

Flux is particularly useful for applications that have global states, such as managing logged-in user states, routing states, or active account states. Using temporary variables or local data to handle these states can be very frustrating.

We do not recommend using Flux to manage routing related data, such as /items/:itemId. It should simply be retrieved and stored in the component’s state, in which case it will be destroyed along with the component when it is destroyed.

For more information on Flux, it is recommended to read The Evolution of Flux Frameworks.

Use Redux

Redux is a predictable state container for JavaScript apps.

If you feel you need Flux or a similar solution, you should check out Redux and learn Dan Abramov’s Getting Started guide to Redux to sharpen your development skills.

Rudux developed the idea of Flux while reducing its complexity.

Flat state

Apis often return nested resources, which makes it difficult for Flux or Redux architectures to handle. We recommend using a library like Normalizr to flatten state as much as possible.

Like this:

const data = normalize(response, arrayOf(schema.user))
 
state = _.merge(state, data.entities)Copy the code

(Isomorphic-FETCH is used to communicate with API)

Using immutable state

Shared mutable data is the root of evil — Pete Hunt, React.js Conf 2015

An immutable object is an object that cannot be modified after being created.

Immutable objects can reduce headaches and improve rendering performance through reference-level comparison checks. For example, in shouldComponentUpdate:

ShouldComponentUpdate (nexProps) {// Return this.props. ImmutableFoo! == nexProps.immutableFoo }Copy the code

How do you implement immutable in JavaScript

The trickier way to do this is to carefully write the following example, always requiring a unit test using deep-freeze-node (freeze before change and verify results after completion).

return { ... state, foo } return arr1.concat(arr2)Copy the code

Trust me, this is the most obvious example.

A simpler and more natural way is to use immutable.js.

import { fromJS } from 'immutable'
 
const state = fromJS({ bar: 'biz' })  
const newState = foo.set('bar', 'baz') Copy the code

Immutable. Js is fast, and the idea behind it is beautiful. Even if you’re not ready to use it, I recommend watching Lee Byron’s video Immutable Data and React to see how it works.

Observables and Reactive solutions

If you don’t like Flux/Redux, or want to be more Reactive, don’t despair! There are plenty of other options, but here’s what you might need:

routing

Now almost all apps have routing capabilities. If you use React. Js in your browser, you’ll touch this dot and select a library for it.

We chose the React-Router from the excellent Rackt community, which always brings high quality resources to react.js fans.

To use the React-Router you need to check its documentation, but more importantly: if you are using Flux/Redux, we recommend that you synchronize route state with Store or global state.

Synchronizing routing state allows Flux/Redux to control routing behavior and allow components to read routing information.

Redux users can use redux-simple-router to make things easier.

Code segmentation, lazy loading

Only a small percentage of WebPack users know that application code can be split into multiple JS packages.

require.ensure([], () => {  
  const Profile = require('./Profile.js')
  this.setState({
    currentComponent: Profile
  })
})Copy the code

This is useful for large applications because the user browser doesn’t have to download code that is rarely used, such as Profile pages.

Multiple JS packages can result in additional HTTP requests, but for HTTP/2 multiplexing, this is not a problem at all.

This can be combined with Chunk hashing to optimize cache hit ratio.

The next version of React – Router will have more support for code separation.

For Future plans for the React-Router, check out Ryan Florence: Welcome to Future of Web Application Delivery.

component

A lot of people complain about JSX, but first, it’s an optional capability in React.

Finally, they are all compiled into JavaScript by Bable. You can continue writing code in JavaScript, but it feels more natural to use JSX when working with HTML. Especially for those who don’t understand JS, they can modify only the relevant parts of HTML.

JSX is an XML-like JavaScript extension that can be used with a simple syntactic compilation tool. Simple things come out

If You want to learn more about JSX, check out the article JSX Looks Like An Abomination — But it’s Good for You.

Using class

React uses the ES2015 Class syntax smoothly.

class HelloMessage extends React.Component {  
  render() {
    return 
       
Hello {this.props.name}
}}Copy the code

We value higher-order components more than mixins, so ditching createClass is more of a syntactic issue than a technical one. The React component’s mixins method will not work in Class syntax. We believe there is no right or wrong way to use createClass and React.component.ponent.

Property Type (PropType)

If you didn’t check the types of props before, you should start correcting them in 2016. It will save you a lot of time in the future, trust me.

MyComponent.propTypes = {  
  isLoading: PropTypes.bool.isRequired,
  items: ImmutablePropTypes.listOf(
    ImmutablePropTypes.contains({
      name: PropTypes.string.isRequired,
    })
  ).isRequired
}

Yes, and also check immutable. Js props using react-immutable types whenever possible.

Higher Order Components

Minins will die, ES6 classes will not support it, we need to find a new way.

What are higher-order components?

PassData({ foo: 'bar' })(MyComponent) Copy the code

Simply, you create a component that inherits from the original component and extends the behavior of the original component. You can use it in a variety of scenarios, such as authentication: requireAuth({role: ‘admin’})(MyComponent) (checks if the user is in an advanced component and jumps if not logged in), or connecting the component to Flux/Redux’s store.

At RisingStack, we also like to separate the logic of the pull and Controller classes into higher-order components to keep the View layer as simple as possible.

test

Good code coverage testing is an important part of the development cycle. Fortunately, the React. Js community has a number of such libraries to help us out.

Component test

Our favorite component test library is AirBnb’s enzyme. With its shallow rendering feature, it’s great to test the logic and render results of components, right? It’s not a replacement for Selenium testing yet, but it takes front-end testing to a new level.

it('simulates click events', () => {  
  const onButtonClick = sinon.spy()
  const wrapper = shallow(
    
  )
  wrapper.find('button').simulate('click')
  expect(onButtonClick.calledOnce).to.be.true
})Copy the code

It looks fresh, doesn’t it?

Do you use CHAI as the assertion library? You’ll love chai-enyzime.

Redux test

It is very simple to test a Reducer, which responds to actions and converts the original state to the new state:

it('should set token', () => {  
  const nextState = reducer(undefined, {
    type: USER_SET_TOKEN,
    token: 'my-token'
  })
 
  // immutable.js state output
  expect(nextState.toJS()).to.be.eql({
    token: 'my-token'
  })
})Copy the code

Testing actions is also easy, but asynchronizing actions is a different story. Redux-mock-store is recommended for testing asynchronous Redux actions.

it('should dispatch action', (done) => { const getState = {} const action = { type: 'ADD_TODO' } const expectedActions = [action] const store = mockStore(getState, expectedActions, done) store.dispatch(action) })

For more in-depth redux testing, please refer to the official documentation.

The use of NPM

While react.js doesn’t rely on code building tools, we recommend Webpack and Browserify, both of which have NPM’s excellent capabilities. Npm has a lot of react.js packages and can also help you gracefully manage dependencies.

(Don’t forget to reuse your own components, which is a great way to optimize your code.)

Bundle size

This isn’t a React problem per se, but most people package it React, so I’ll mention it here.

When you build source code, keep the package size in mind. To keep it to a minimum, you need to think about how to require/import dependencies.

Looking at the code snippet below, there are two ways that can have a significant impact on the output:

import { concat, sortBy, map, sample } from 'lodash'
 
// vs.
import concat from 'lodash/concat';  
import sortBy from 'lodash/sortBy';  
import map from 'lodash/map';  
import sample from 'lodash/sample';  Copy the code

See Reduce Your bundle.js File Size By Doing This One Thing for more details.

We like to separate the code into vendor.js and app.js, because third party code updates much less frequently than we do.

By hashing the output file (chunk hash in WebPack) and using a long cache, we can significantly reduce the amount of code that users need to download to access it. Combined with lazy loading code, the optimization effect can be imagined.

If you’re new to WebPack, check out the awesome React WebPack guide.

Hot Reload at the component level

If you’ve ever written a single-page application using Livereload, you probably know how annoying it can be to save a bit of code and refresh the entire page while doing something state-related. You need to click through to where you started, and then crash through the repetition.

In React development, it’s possible to reload a component while keeping its state constant — yay!

To build hot reload, refer to react-transform-Boilerplate.

Using ES2015

As mentioned earlier, JSX used in react.js will eventually be compiled by babel.js.

Bable doesn’t stop there, it lets us use ES6/ES2015 mindfully in the browser. At RisingStack, we use ES2015 features on both the server and client side, and ES2015 is available in the latest version of LTS Node.js.

Code checks (Linters)

You probably have a code specification for your code, but do you know the various code specifications for React? We recommend that you choose a code specification and follow the instructions below.

On RisingStack, we forced linters to run on continuous integration (CI) systems, and git push capabilities. Look at pre-push and pre-commit.

We use the standard JavaScript code style and use eslint-plugin-react to examine the react.js code.

(Yes, we don’t use semicolons anymore.)

GraphQL and Relay

GraphQL and Relay are related new technologies. At RisingStack, we don’t use them in production, so keep an eye on them for now.

We wrote a Relay MongoDB ORM called Graffiti that can be used to create GraphQL Server using your existing Mongoose Models.

If you want to learn these new techniques, we suggest you check out the library and write some demos.

These react.js best practices are central

Some of the best technologies and libraries have nothing to do with React. The key is to focus on what the community is doing. The React community was inspired by the Elm architecture in 2015.

If you know of any other react.js tools you should use in 2016, let us know in the comments.