React.js Best Practices for 2016

来源:http://www.cnblogs.com/wenzhuan/archive/2016/04/20/5413523.html
-Advertisement-
Play Games

2015 was the year of React with tons of new releases and developer conferences dedicated to the topic all over the world. For a detailed list of the m ...


2015 was the year of React with tons of new releases and developer conferences dedicated to the topic all over the world. For a detailed list of the most important milestones of last year, check out our React in 2015 wrap up.

 

The most interesting question for 2016: How should we write an application and what are the recommended libraries?

 

As a developer working for a long time with React.js I have my own answers and best practices, but it's possible that you won’t agree on everything with me. I’m interested in your ideas and opinions: please leave a comment so we can discuss them.

 

React.js logo - Best Practices for 2016

 

If you are just getting started with React.js, check out our React.js tutorial, or the React howto by Pete Hunt.

 

Dealing with data

 

Handling data in a React.js application is super easy, but challenging at the same time. 

It happens because you can pass properties to a React component in a lot of ways to build a rendering tree from it; however it's not always obvious how you should update your view.

 

2015 started with the releases of different Flux libraries and continued with more functional and reactive solutions.

 

Let's see where we are now:

 

Flux

 

According to our experience, Flux is often overused (meaning that people use it even if they don't even need it).

 

Flux provides a clean way to store and update your application's state and trigger rendering when it's needed.

 

Flux can be useful for the app's global states like: managing logged in user, the state of a router or active account but it can turn quickly into pain if you start to manage your temporary or local data with it.

 

We don’t recommend using Flux for managing route-related data like /items/:itemId. Instead, just fetch it and store it in your component's state. In this case, it will be destroyed when your component goes away.

 

If you need more info about Flux, The Evolution of Flux Frameworks is a great read.

 

Use redux

 

Redux is a predictable state container for JavaScript apps.

 

If you think you need Flux or a similar solution you should check out redux and Dan Abramov's Getting started with redux course to quickly boost your development skills.

 

Redux evolves the ideas of Flux but avoids its complexity by taking cues from Elm.

 

Keep your state flat

 

API's often return nested resources. It can be hard to deal with them in a Flux or Redux-based architecture. We recommend to flatten them with a library like normalizr and keep your state as flat as possible.

 

Hint for pros:

 

const data = normalize(response, arrayOf(schema.user))

 

state = _.merge(state, data.entities)  

(we use isomorphic-fetch to communicate with our APIs)

 

Use immutable states

 

Shared mutable state is the root of all evil - Pete Hunt, React.js Conf 2015

 

Immutable logo for React.js Best Practices 2016

 

Immutable object is an object whose state cannot be modified after it is created.

 

Immutable objects can save us all a headache and improve the rendering performance with their reference-level equality checks. Like in the shouldComponentUpdate:

 

shouldComponentUpdate(nexProps) {  

 // instead of object deep comparsion

 return this.props.immutableFoo !== nexProps.immutableFoo

}

How to achieve immutability in JavaScript? 

The hard way is to be careful and write code like the example below, which you should always check in your unit tests with deep-freeze-node (freeze before the mutation and verify the result after it).

 

return {  

  ...state,

  foo

}

 

return arr1.concat(arr2)  

Believe me, these were the pretty obvious examples.

 

The less complicated way but also less natural one is to use Immutable.js.

 

import { fromJS } from 'immutable'

 

const state = fromJS({ bar: 'biz' })  

const newState = foo.set('bar', 'baz')  

Immutable.js is fast, and the idea behind it is beautiful. I recommend watching the Immutable Data and React video by Lee Byron even if you don't want to use it. It will give deep insight to understand how it works.

 

Observables and reactive solutions

 

If you don't like Flux/Redux or just want to be more reactive, don't be disappointed! There are other solutions to deal with your data. Here is a short list of libraries what you are probably looking for:

 

cycle.js ("A functional and reactive JavaScript framework for cleaner code")

rx-flux ("The Flux architecture with RxJS")

redux-rx ("RxJS utilities for Redux.")

mobservable ("Observable data. Reactive functions. Simple code.")

Routing

 

Almost every client side application has some routing. If you are using React.js in a browser, you will reach the point when you should pick a library.

 

Our chosen one is the react-router by the excellent rackt community. Rackt always ships quality resources for React.js lovers.

 

To integrate react-router check out their documentation, but what's more important here: if you use Flux/Redux we recommend to keep your router's state in sync with your store/global state.

 

Synchronized router states will help you to control router behaviors by Flux/Redux actions and read router states and parameters in your components.

 

Redux users can simply do it with the redux-simple-router library.

 

Code splitting, lazy loading

 

Only a few of webpack users know that it's possible to split your application’s code to separate the bundler's output to multiple JavaScript chunks:

 

require.ensure([], () => {  

  const Profile = require('./Profile.js')

  this.setState({

    currentComponent: Profile

  })

})

It can be extremely useful in large applications because the user's browser doesn't have to download rarely used codes like the profile page after every deploy.

 

Having more chunks will cause more HTTP requests - but that’s not a problem with HTTP/2 multiplexed.

 

Combining with chunk hashing you can also optimize your cache hit ratio after code changes.

 

The next version of react-router will help a lot in code splitting.

 

For the future of react-router check out this blog post by Ryan Florence: Welcome to Future of Web Application Delivery.

 

Components

 

A lot of people are complaining about JSX. First of all, you should know that it’s optional in React.

 

At the end of the day, it will be compiled to JavaScript with Babel. You can write JavaScript instead of JSX, but it feels more natural to use JSX while you are working with HTML. 

Especially because even less technical people could still understand and modify the required parts.

 

JSX is a JavaScript syntax extension that looks similar to XML. You can use a simple JSX syntactic transform with React. - JSX in depth

 

If you want to read more about JSX check out the JSX Looks Like An Abomination - But it’s Good for You article.

 

Use Classes

 

React works well with ES2015 classes.

 

class HelloMessage extends React.Component {  

  render() {

    return <div>Hello {this.props.name}</div>

  }

}

We prefer higher order components over mixins so for us leaving createClass was more like a syntactical question rather than a technical one. We believe there is nothing wrong with using createClass over React.Component and vice-versa.

 

PropType

 

If you still don't check your properties, you should start 2016 with fixing this. It can save hours for you, believe me.

 

MyComponent.propTypes = {  

  isLoading: PropTypes.bool.isRequired,

  items: ImmutablePropTypes.listOf(

    ImmutablePropTypes.contains({

      name: PropTypes.string.isRequired,

    })

  ).isRequired

}

Yes, it's possible to validate Immutable.js properties as well with react-immutable-proptypes.

 

Higher order components

 

Now that mixins are dead and not supported in ES6 Class components we should look for a different approach.

 

What is a higher order component?

 

PassData({ foo: 'bar' })(MyComponent)  

Basically, you compose a new component from your original one and extend its behaviour. You can use it in various situations like authentication: requireAuth({ role: 'admin' })(MyComponent) (check for a user in higher component and redirect if the user is not logged in) or connecting your component with Flux/Redux store.

 

At RisingStack, we also like to separate data fetching and controller-like logic to higher order components and keep our views as simple as possible.

 

Testing

 

Testing with good test coverage must be an important part of your development cycle. Luckily, the React.js community came up with excellent libraries to help us achieve this.

 

Component testing

 

One of our favorite library for component testing is enzyme by AirBnb. With it's shallow rendering feature you can test logic and rendering output of your components, which is pretty amazing. It still cannot replace your selenium tests, but you can step up to a new level of frontend testing with it.

 

it('simulates click events', () => {  

  const onButtonClick = sinon.spy()

  const wrapper = shallow(

    <Foo onButtonClick={onButtonClick} />

  )

  wrapper.find('button').simulate('click')

  expect(onButtonClick.calledOnce).to.be.true

})

Looks neat, isn't it?

 

Do you use chai as assertion library? You will like chai-enyzime!

 

Redux testing

 

Testing a reducer should be easy, it responds to the incoming actions and turns the previous state to a new one:

 

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 simple until you start to use async ones. For testing async redux actions we recommend to check out redux-mock-store, it 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 deeper redux testing visit the official documentation.

 

使用native react開發穩賺理財助手app ing

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • background-size的基本屬性 background-size: 可以設定背景圖像的尺寸,該屬性是css3中的,在移動端使用的地方很多,比如最常見的地方在做響應性佈局的時候,比如之前做的項目中有輪播圖片,為了自適應不同大小解析度的圖片,我門需要使用css3中的媒體查詢來針對不同的解析度設置 ...
  • JavaScript是一個絕冠全球的編程語言,可用於Web開發、移動應用開發(PhoneGap、Appcelerator)、伺服器端開發(Node.js和Wakanda)等等。JavaScript還是很多新手踏入編程世界的第一個語言。既可以用來顯示瀏覽器中的簡單提示框,也可以通過nodebot或no ...
  • 如果你看到這篇文章,我確信你毫無疑問會認為jQuery是一個使用簡便的庫。jQuery可能使用起來很簡單,但是它仍然有一些奇怪的地方,對它基本功能和概念不熟悉的人可能會難以掌握。但是不用擔心,我下麵已經把代碼劃分成小部分,做了一個簡單的指導。那些語法看起來可能過於複雜,但是如果進入到它的思想和模式中 ...
  • 本文將向大家介紹如何利用CSS3的新樣式屬性製作一個HTML5的Logo。我們先來看看最終的效果: 不要懷疑,上面的logo完全由HTML+CSS實現。我們將logo劃分為盾形、數字5和輻射背景三大部分,下麵將分別實現每個部分。 盾形 盾形在外形上是左右對稱的,因此我們可先完成左半邊,右半邊可複製過 ...
  • 這其中的jquery代碼中的獲得高度用的clientHeight,介紹一下幾種不同的獲得方式以及他們的差別。 這四種瀏覽器分別為IE(Internet Explorer)、NS(Netscape)、Opera、FF(FireFox)。 clientHeight 大家對 clientHeight 都沒 ...
  • npm install <name>安裝nodejs的依賴包 例如npm install express 就會預設安裝express的最新版本,也可以通過在後面加版本號的方式安裝指定版本,如npm install [email protected] npm install <name> -g 將包安裝到全局 ...
  • 這個圖片是我用xmind編輯的。歡迎大家來糾正或添加! 再來說說我對網站開發的理解與碰到的問題。 網站的前端有幾個部分我覺得很重要: 1.優雅的文字提示 2.合理的頁面設計 3.適當的腳本特效 一進入這個網站,就讓人有一種非常舒適的感覺。並且在舒適的基礎上有奪人眼球的特效,再有貼心的提示,我相信肯定 ...
  • do_Http組件就是實現http/https協議的組件. 首先要說明一下,Do平臺只是一個移動端開發的平臺,不涉及任何後臺服務端的技術,你可以使用你自己任何熟悉的語言和技術來實現服務端,do_Http組件就是用來和服務端通信。 http是一個最基礎的應用層的通信協議,開發者應該很熟悉,但是在QQ群 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...