redux常見問題答疑

爲何使用redux

React的核心是將UI組件化,由數據驅動UI的展示。可是如何管理數據模型、組件與數據模型之間的通訊,react並無很好的解決方案。Redux由flux演變而來,同時簡化了Flux的流程。html

僅僅使用react進行開發的痛點

  1. 組件嵌套層級深,回調地獄。你可能會在一個較深層次的組件裏須要更新全局state的某個字段,卻無奈只能經過從頂層組件一層一層傳遞下來的props進行回調。react

  2. 頁面的state不可預測。因爲state缺少一種可預測的機制,致使用戶在進行一些頁面操做(更改state),或者異步請求有新的數據從服務端返回的時候,state的變化已經不可控制,很容易產生buggit

redux是怎麼解決痛點的?

一、經過react-redux提供的Provider組件,在根組件外面包一層,這樣根組件,以及全部的子組件都能拿到store。實現的原理是基於React自身提供的context屬性,可是react官方不推薦直接在組件中使用this.context。因此react-redux提供了另外一種方法connect,經過connect將普通的UI組件升級爲容器組件,同時將獲取store的細節也一併封裝在生成容器組件的代碼中,從而容器組件能夠直接拿到storegithub

<Provider store={store}>
<App/>
</Provider>

// 定義App組件
class Foo extends React.Component{
    render() {
    const { text } = this.props;
    return <div>{text}</div>;
  }
}
const App = connect(
  mapStateToProps,
  mapDispatchToProps
)(Foo);

二、使用純函數修改state,保證state變化可預測。每次更改都返回一個全新的state。
三、遵照容器組件與展現組件分離的原則。這是redux一個重要的思想,容器組件和展現組件各司其職。redux

容器組件

容器組件負責如下幾件事情:性能優化

  1. 處理數據邏輯數據結構

  2. 將store中的state轉變爲props傳遞給展現組件,對應mapStateToProps框架

  3. 將注入了dispatch的函數做爲props傳遞給展現組件,對應mapDispatchToProps異步

  4. 有狀態的(展現組件則是無狀態的)ide

  5. 發起action,更新state

  6. 沒有DOM標籤,沒有樣式

展現組件

可複用的組件,又稱爲「傻瓜組件」,僅僅經過容器組件傳進來的props進行UI展現,以及操做回調。感知不到redux的存在,脫離redux框架也能使用,儘可能保持無狀態(可包含少許的UI狀態),有如下幾條原則:

  1. 不理解數據邏輯:不關心數據是如何獲得的,也不關心數據是如何改變的

  2. 只經過props獲取數據和操做回調

  3. 基本是無狀態的:必須有的話,能夠是UI的狀態

何時引入容器組件

在引入以前,你能夠先只用展現組件來構建App。當你發現有些組件並不會用到傳進來的屬性,而僅僅只是把它往下傳給子組件的時候(而且層級比較深,超過兩層),你就要考慮引入容器組件了。

爲何使用immutable.js

首先,在沒有immutable.js的狀況下,碰到較深層次的數據結構時,更新state會變得很麻煩。

舊的state:

{
  priceInfo: {
    price: 200,
    promotion: {
      offValue: 30
    }
  }
}

如今須要只更新offValue的值爲50,該怎麼處理呢?

let newState = _.cloneDeep(this.state);
newState.priceInfo.promotion.offValue = 50;
this.setState(newState);

能夠看到,須要先深度複製一份this.state,而後修改offValue的值,最後執行setState。除了這個過程的有點複雜,另外深度複製對象是挺耗性能的一件事。而經過Immutable.js,咱們只須要這樣作:

let initialState = Immutable.fromJS({
  priceInfo: {
    price: 200,
    promotion: {
      offValue: 30
    }
  }
});
this.setState(initialState.setIn(['priceInfo', 'promotion', 'offValue']), 50);

immutable.js帶來的性能提高

React作性能優化時常常用到 shouldComponentUpdate,只有深度比較才能得出正確的值,決定是否render,而深度比較是十分消耗性能的。Immutable 則提供了簡潔高效的判斷數據是否變化的方法,只需 ===is 比較就能知道是否須要執行render(),而這個操做幾乎零成本,因此能夠極大提升性能。

immutable.js的數據結構如何正確使用...擴展運算符

在jsx的語法中,你已經習慣了使用擴展運算符來傳遞props,以下所示:

const titleInfo = {
  title: '主標題',
  subTitle: '副標題'
};

...

import Title from 'title';

render() {
  return (
    <Title {...titleInfo}/>
  );
}

可是若是你要傳遞的數據是Immutable.Map類型的,使用...擴展運算符,獲得的數據可能與你指望的不太同樣,由於Immutable.Map的實例對象並非plain object。{...titleInfo}等同於Object.assign({}, titleInfo)。Immutable.js提供了一種方法,能夠實現這種轉換,若是是Map實例,只需調用toObject()(不要調用深度複製的toJS),就能夠將Immutable.js的Map對象轉變爲可使用...擴展運算符的plain object。

相關文章
相關標籤/搜索