According to $ {Description}: React-related topics are still hot in recent months. I believe that more and more developers are trying such a technology, and our team is constantly summing up experience on PCs and mobile terminals. 2016 is coming. This should be a year of maturity for React. Whether you are a newbie or have some knowledge about React, it is time to summarize the best practices, let's take a look at some good practices that foreign developers have summarized ~
2015 can be regarded as the year of React. Topics about its version release and Developer Conference are distributed all over the world. For more information about the Development Milestones of last year's React, see React 2015.
The most interesting question in 2016 may be: how should we write an application? What recommended libraries or frameworks are there?
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 to all the points I mentioned. I am very interested in your thoughts and comments. Please leave a message for discussion.
If you are just getting started with React. js, read the React. js tutorial or the React howto of Pete Hunt.
Data Processing
Processing data in React. js applications is extremely simple, but there are still some challenges.
This is because you can pass attribute data to a React component in multiple ways to build a rendering tree. However, this method does not always show whether you should update some views.
A batch of Flux libraries with stronger functions and responsive solutions emerged in 2015. Let's take a look at them together:
Flux
Based on our experience, Flux is usually over-used (that is, it is used in scenarios that are not needed ).
Flux provides a fresh way to store and manage application statuses and trigger rendering as needed.
Flux for thoseThis article will not translate the global state of an application to correspond to the state Concept in React.For example, you can manage the logon user status, Route status, or active account status. If you use temporary variables or local data to process these statuses, it can be a headache.
We do not recommend using Flux to manage route-related data, such as/items/: itemId. It should only be obtained and stored in the state of the component. In this case, it will be destroyed together when the component is destroyed.
For more information about Flux, read The Evolution of Flux Frameworks.
Use Redux
Redux is a predictable state container for JavaScript apps.
If you think you need Flux or similar solutions, you should take a look at redux and learn Dan Abramov's redux Getting Started Guide to strengthen your development skills.
Rudux developed the Flux idea and reduced its complexity.
Flat state
APIS usually return nested resources, which makes the Flux or Redux architecture hard to handle. We recommend that you use the normalizr class library.Flat state as much as possible.
Like this:
const data = normalize(response, arrayOf(schema.user))state = _.merge(state, data.entities
(We use isomorphic-fetch to communicate with Apis)
Use immutable state
Shared variable data is the root of evil-Pete Hunt, React. js Conf 2015
An unchangeable object is an object that cannot be modified after creation.
Immutable objects can reduce the work that makes us a headache and improve rendering performance through reference-level comparison checks. For example, in shouldComponentUpdate:
ShouldComponentUpdate (nexProps) {// no in-depth comparison of objects return this. props. immutableFoo! = NexProps. immutableFoo}
How to Implement immutable in JavaScript
The troublesome way is to carefully compile the following example. You always need to use deep-freeze-node (freeze before the change and verify the result after the change) for unit testing.
return { ...state, foo} return arr1.concat(arr2)
Believe me, this is the most obvious example.
The 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')
Immutable. js is very fast, and its ideas are also wonderful. Even if you are not ready to use it, we recommend that you check the video Immutable Data and React of Lee Byron to understand its internal implementation principles.
Observables and reactive Solution
If you do not like Flux/Redux or want to be more reactive, don't be disappointed! There are many other solutions for you to choose from. Here you may need:
Cycle. js ("a more refreshing reactive framework ")
Rx-flux ("product of combination of Flux and Rxjs ")
Redux-rx ("Redux Rxjs tool library ")
Mobservable ("observability data, reactive functions, and concise code ")
Routing
Almost all apps now have the routing function. If you use React. js in your browser, you will be exposed to this point and select a library for it.
We chose the react-router from the excellent rackt community, which can always bring high-quality resources to React. js fans.
To use react-router, you need to check its documentation. But more importantly, if you use Flux/Redux, we recommend that you synchronize the route state with the store or global state.
Synchronous routing state allows Flux/Redux to control routing behavior and allows components to read routing information.
Redux users can use redux-simple-router to save some trouble.
Code segmentation and lazy loading
Only a small part of webpack users know that application code can be divided into multiple js packages.
require.ensure([], () => { const Profile = require('./Profile.js') this.setState({ currentComponent: Profile })})
This is very useful for large applications, because the user's browser does not need to download the code that is rarely used, such as the Profile page.
Multiple js packages will cause additional HTTP requests, but multiplexing of HTTP/2 is not a problem at all.
Combined with chunk hashing, the cache hit rate can be optimized.
The next version of react-router will support code separation.
For Future plans for react-router, visit the blog Ryan Florence: ** to Future of Web Application Delivery.
Components
Many people complain about JSX, but first you need to know that it is only an optional capability in React.
Finally, they are all compiled into JavaScript by Bable. You can continue to write code using JavaScript, but it is more natural to use JSX when processing HTML. Especially for those who do not understand js, they can modify only HTML-related parts.
JSX is a JavaScript extension similar to XML and can be used with a simple syntax compilation tool. -- In-depth introduction to JSX
For more information about JSX, see the article JSX Looks Like An Abomination-But it's Good for You.
Usage class
The Class Syntax of ES2015 can be smoothly used in React.
class HelloMessage extends React.Component { render() { returnHello {this.props.name}}}
We pay more attention to the former between higher-level components and mixins, so abandoning createClass is more like a syntax problem than a technical problem. (Note: In the Class syntax, the mixins method of the React component cannot be used .) We believe that createClass and React. Component are not correct or wrong.
Property type (PropType)
If you did not check the props type before, 2016 you should begin to correct it. It will save you a lot of time in the future. Believe me.
MyComponent.propTypes = { isLoading: PropTypes.bool.isRequired, items: ImmutablePropTypes.listOf( ImmutablePropTypes.contains({ name: PropTypes.string.isRequired, }) ).isRequired}
Yes, and try to use react-immutable-proptypes to check props of Immutable. js.
Higher order components)
Minins will die, and ES6 Class will not support it. We need to find new methods.
What is an advanced component?
PassData({ foo: 'bar' })(MyComponent)
Simply, you create a component that inherits from the native component and extends the behavior of the original component. You can use it in multiple scenarios, such as authentication: requireAuth ({role: 'admin'}) (MyComponent) (check user permissions in higher-level components, if you have not logged on, you can jump to or connect the component to the store of Flux/Redux.
In RisingStack, we also like to separate the logic of Data pulling and controller classes into higher-order components, so that we can 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 many such libraries to help us.
Component Test
Our favorite Component Test Library is AirBnb's enzyme. With its light rendering feature, you can test the component's logic and rendering results, which is great, right? It cannot replace selenium tests now, but has elevated the front-end test 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})
It looks refreshing, isn't it?
Do you use chai as the assertion library? You will like chai-enyzime.
Redux Testing
Testing a reducer is very simple. It responds to actions and converts the original state to a 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' })})
Testing actions is also simple, but asynchronous actions is different. We recommend redux-mock-store to test asynchronous redux actions, which can help a lot.
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, see the official documentation.
Use npm
Although React. js does not rely on code building tools, we recommend Webpack and Browserify, both of which have excellent npm capabilities. Npm has many React. js packages and can help you manage dependencies elegantly.
(Do not forget to reuse your own components. This is an excellent way to optimize the code .)
Bundle size)
This is not a React-related issue, but most people will package their React, so I will mention it here.
When you build the source code, you need to pay attention to the package size. To minimize its size, you need to think about how to request/import dependencies.
You can view the following code snippets in either of the following ways to significantly affect 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';
View Reduce Your bundle. js File Size By Doing This One Thing for more details.
We like to separate code into vendors. js and app. js, because the update frequency of Third-Party code is much lower than that of our own.
Name the output file by hash (the chunk hash in WebPack) and use the long cache. We can significantly reduce the code to be downloaded by users. Combined with code lazy loading, the optimization results can be imagined.
If you are still unfamiliar with WebPack, go to the awesome React webpack guide.
Component-level hot reload
If you have used livereload to write a single page application, you may know that when you are dealing with status-related tasks, a bit of code is Refresh to save the entire page. This experience is annoying. You need to gradually click the operation to the previous step, and then crash in such repetition.
In React development, You can reload a component and keep its state unchanged!
To set up hot reload, refer to react-transform-boilerplate.
Use ES2015
As mentioned above, the JSX used in React. js will eventually be compiled by Babel. js.
Bable is more powerful than that. It allows us to use ES6/ES2015 in a browser. At RisingStack, we have used ES2015 features on both the server side and the client side. ES2015 can be used in the latest LTS Node. js version.
Code check (Linters)
Maybe you have developed code specifications for your code, but do you know the various code specifications of React? We recommend that you select a code specification and follow the instructions below.
At RisingStack, we force the linters to run in the CI system, which has the git push function. View pre-push and pre-commit.
We use the standard JavaScript code style and eslint-plugin-react to check the React. js code.
(Yes, we no longer use semicolons)
GraphQL and Relay
GraphQL and Relay are related new technologies. At RisingStack, we do not use them in the production environment, so stay tuned for the moment.
We have written a Relay MongoDB ORM called graffiti. You can use your existing mongoose models to create a GraphQL server.
If you want to learn these new technologies, we recommend that you read this library and write a few demos for fun.
Core points of these React. js Best Practices
Some excellent technologies and libraries have nothing to do with React. The key is to pay attention to what the Community is doing. In 2015, the React community was inspired by the Elm architecture.
If you know the React. js tool that everyone should use in 2016, leave a message to us.