react-redux文檔翻譯

英文文檔鏈接

API


<Provider store>

使得層級之下的組件可以通過connect()函數(shù)訪問到Redux store。通常,如果你不將父組件或者根組件用<Provider>組件包裹起來的話,你是不可以使用connect()函數(shù)的。

Props

  • store (Redux Store): 應用中的單一數(shù)據(jù)源
  • children (ReactElement) :你的根組件

Example

Vanilla React
ReactDOM.render(
  <Provider store={store}>
    <MyRootComponent />
  </Provider>,
  rootEl
)
React Router
ReactDOM.render(
  <Provider store={store}>
    <Router history={history}>
      <Route path="/" component={App}>
        <Route path="foo" component={Foo}/>
        <Route path="bar" component={Bar}/>
      </Route>
    </Router>
  </Provider>,
  document.getElementById('root')
)

connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])

將一個React組件連接到Redux store上去。connectconnectAdvanced的一層包裝,對外提供了一套對于大多數(shù)開發(fā)情況下方便的API。
它并不更改傳入的組件,而是返回一個新的、連接到store的組件共你使用。

Arguments

  • [mapStateToProps(state, [ownProps]): stateProps] (Function):如果這個參數(shù)指定了,這個新組件將會訂閱store的更新。這意味著每次store更新,mapStateToProps將會被調用。mapStateToProps的結果是一個plain object,這個結果會和組件的props融合為新的props。如果你不想訂閱store的更新,傳入null或者undefined。

    如果你的mapStateToProps傳入了兩個參數(shù),那么調用它時,store將會作為第一個參數(shù),connected component的props將會作為第二個參數(shù),并且也會重新觸發(fā),如果判定機制——淺相等比較判斷組件接收到新的props。

    注意:在你需要對渲染性能有更多的控制的情況下,mapStateToProps也可以返回一個函數(shù)。在這種情況下,那個返回的函數(shù)將被特定的組件作為mapStateTOProps。這使得你可以完成單一實例記憶化(per-instance memoization)You can refer to #279 and the tests it adds for more details. 大多數(shù)應用不需要用到它。

    mapStateToProps接受一個store參數(shù)時,它將返回一個對象,這個對象將作為組建的props。我們通常將其稱作selector,Use reselect to efficiently compose selectors and compute derived data.

  • [mapDispatchToProps(dispatch, [ownProps]): dispatchProps] (Object or Function):如果傳入的是object,每一個其中的函數(shù)都應該是一個Redux action creator。一個擁有同樣的函數(shù)的對象將會融合入組件的props,但不同的是這個對象的每個action creator將會作為dispatch的參數(shù),這樣它們就可以直接執(zhí)行。

    如果傳入的是一個函數(shù),那么這個函數(shù)將會接受dispatch作為它的第一個參數(shù)。It’s up to you to return an object that somehow uses dispatch
    to bind action creators in your own way. (Tip: you may use the bindActionCreators()
    helper from Redux.)

    如果你的mapDispatchToProps傳入了兩個參數(shù),那么dispatch將作為第一個參數(shù),被連接的組件傳入的props將作為第二個參數(shù)。每當組將接收到新的參數(shù)時,這個函數(shù)都將被觸發(fā)。

    如果你不指定mapDispatchToProps參數(shù),那么默認的mapDispatchToProps實現(xiàn)會將dispatch作為props連接的組件。

    Note: in advanced scenarios where you need more control over the rendering performance, mapDispatchToProps()
    can also return a function. In this case, that function will be used as mapDispatchToProps()
    for a particular component instance. This allows you to do per-instance memoization. You can refer to #279 and the tests it adds for more details. Most apps never need this.

  • [mergeProps(stateProps, dispatchProps, ownProps): props] (Function):如果這個函數(shù)指定了,那么傳入這個函數(shù)的前兩個參數(shù)分別為mapStateToProps(), mapDispatchToProps()的執(zhí)行結果,第三個參數(shù)為組件自身的props。這個函數(shù)將會返回一個plain object,這個結果將成為被包裹組件的props。你也許可以用這個回調函數(shù),根據(jù)組件的 props 來篩選部分的 state 數(shù)據(jù),或者把 props 中的某個特定變量與 action creator 綁定在一起。如果你省略這個參數(shù),默認情況下返回 Object.assign({}, ownProps, stateProps, dispatchProps)的結果。

  • [options] (Object):如果指定這個參數(shù),可以進一步定制connector的行為。除了connectAdvanced()可以傳入的選項之外,connect()還可以接收以下的額外選項。

    • [pure](Boolean):如果為true,當相關的state/props的相等判斷機制判斷其沒有發(fā)生變化時,connect()將會避免組建的重新render()以及mapStateToProps, mapDispatchToProps, mergeProps的調用,前提是該組件是一個“純”組件,即該組件不依賴于任何外部的輸入和內部的state,只依賴于props和從connect()函數(shù)獲取到的store的數(shù)據(jù)。默認值為true。
    • [areStatesEqual] (Function): When pure, compares incoming store state to its previous value. Default value: strictEqual (===)
    • [areOwnPropsEqual] (Function): When pure, compares incoming props to its previous value. Default value: shallowEqual
    • [areStatePropsEqual] (Function): When pure, compares the result of mapStateToProps to its previous value. Default value: shallowEqual
    • [areMergedPropsEqual] (Function): When pure, compares the result of mergeProps to its previous value. Default value: shallowEqual
    • [storeKey] (String): The key of the context from where to read the store. You probably only need this if you are in the inadvisable position of having multiple stores. Default value: 'store'
mapStateToProps和mapDispatchToProps函數(shù)的元數(shù)(arity,可以理解為函數(shù)長度)決定了它們是否能接收到ownProps作為第二個參數(shù)。

注意:如果定義一個包含強制性參數(shù)函數(shù)(這個函數(shù)的長度為 1)時,ownProps不會傳到 mapStateToPropsmapDispatchToProps 中。舉個例子,如下這樣定義一個函數(shù)時將不會接收到 ownProps 作為第二個參數(shù)。

function mapStateToProps(state) {
  console.log(state); // state
  console.log(arguments[1]); // undefined
}
//因為這個函數(shù)有一個參數(shù)有默認值,所以這個函數(shù)的長度仍然為1
const mapStateToProps = (state, ownProps = {}) => {
  console.log(state); // state
  console.log(ownProps); // undefined
}

當函數(shù)沒有強制性的參數(shù)或兩個參數(shù)時將接收到 ownProps。

const mapStateToProps = (state, ownProps) => {
  console.log(state); // state
  console.log(ownProps); // ownProps
}
function mapStateToProps() {
  console.log(arguments[0]); // state
  console.log(arguments[1]); // ownProps
}
const mapStateToProps = (...args) => {
  console.log(args[0]); // state
  console.log(args[1]); // ownProps
}
Optimizing(優(yōu)化) connect when options.pure is true

options.puretrue的時候,connect將執(zhí)行幾個相等檢測,以此避免不必要的mapStateToProps, mapDispatchToProps, mergeProps調用,最終導致render()。這些相等檢測包括areStatesEqual, areOwnPropsEqual, areStatePropsEqual, 和areMergedPropsEqual。盡管默認參數(shù)可能適合于99%的場景,但是出于性能或者其他原因,你也許像自定義它們的實現(xiàn),下面是幾個例子。

  • 如果mapStateToProps需要花費昂貴的計算時間并且只關心你的狀態(tài)的一小部分,那么你可以重寫areStatesEqual。舉個例子:areStatesEqual: (next, prev) => prev.entities.todos === next.entities.todos。

  • 當你使用不純的reducers時,你或許希望重寫areStatesEqual,使它一直返回false。

  • You may wish to override areOwnPropsEqual as a way to whitelist incoming props. You'd also have to implement mapStateToProps, mapDispatchToProps and mergeProps to also whitelist props. (It may be simpler to achieve this other ways, for example by using recompose's mapProps.)

  • You may wish to override areStatePropsEqual to use strictEqual if your mapStateToProps uses a memoized selector that will only return a new object if a relevant prop has changed. This would be a very slight performance improvement, since would avoid extra equality checks on individual props each time mapStateToProps is called.

  • You may wish to override areMergedPropsEqual to implement a deepEqual if your selectors produce complex props. ex: nested objects, new arrays, etc. (The deep equal check should be faster than just re-rendering.)

返回值

根據(jù)配置信息,返回一個注入了 state 和 action creator 的 React高階組件。這個組件是由connectAdvanced創(chuàng)建的。

例子

Inject just dispatch and don't listen to store
export default connect()(TodoApp)
Inject all action creators (addTodo, completeTodo, ...) without subscribing to the store
import * as actionCreators from './actionCreators'

export default connect(null, actionCreators)(TodoApp)
Inject dispatch and every field in the global state

Don’t do this! It kills any performance optimizations because TodoApp will rerender after every state change.
It’s better to have more granular connect() on several components in your view hierarchy that each only
listen to a relevant slice of the state.

export default connect(state => state)(TodoApp)
Inject dispatch and todos
function mapStateToProps(state) {
  return { todos: state.todos }
}

export default connect(mapStateToProps)(TodoApp)
Inject todos and all action creators
import * as actionCreators from './actionCreators'

function mapStateToProps(state) {
  return { todos: state.todos }
}

export default connect(mapStateToProps, actionCreators)(TodoApp)
Inject todos and all action creators (addTodo, completeTodo, ...) as actions
import * as actionCreators from './actionCreators'
import { bindActionCreators } from 'redux'

function mapStateToProps(state) {
  return { todos: state.todos }
}

function mapDispatchToProps(dispatch) {
  return { actions: bindActionCreators(actionCreators, dispatch) }
}

export default connect(mapStateToProps, mapDispatchToProps)(TodoApp)
Inject todos and a specific action creator (addTodo)
import { addTodo } from './actionCreators'
import { bindActionCreators } from 'redux'

function mapStateToProps(state) {
  return { todos: state.todos }
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators({ addTodo }, dispatch)
}

export default connect(mapStateToProps, mapDispatchToProps)(TodoApp)
Inject todos and specific action creators (addTodo and deleteTodo) with shorthand syntax
import { addTodo, deleteTodo } from './actionCreators'

function mapStateToProps(state) {
  return { todos: state.todos }
}

const mapDispatchToProps = {
  addTodo,
  deleteTodo
}

export default connect(mapStateToProps, mapDispatchToProps)(TodoApp)
Inject todos, todoActionCreators as todoActions, and counterActionCreators as counterActions
import * as todoActionCreators from './todoActionCreators'
import * as counterActionCreators from './counterActionCreators'
import { bindActionCreators } from 'redux'

function mapStateToProps(state) {
  return { todos: state.todos }
}

function mapDispatchToProps(dispatch) {
  return {
    todoActions: bindActionCreators(todoActionCreators, dispatch),
    counterActions: bindActionCreators(counterActionCreators, dispatch)
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(TodoApp)
Inject todos, and todoActionCreators and counterActionCreators together as actions
import * as todoActionCreators from './todoActionCreators'
import * as counterActionCreators from './counterActionCreators'
import { bindActionCreators } from 'redux'

function mapStateToProps(state) {
  return { todos: state.todos }
}

function mapDispatchToProps(dispatch) {
  return {
    actions: bindActionCreators(Object.assign({}, todoActionCreators, counterActionCreators), dispatch)
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(TodoApp)
Inject todos, and all todoActionCreators and counterActionCreators directly as props
import * as todoActionCreators from './todoActionCreators'
import * as counterActionCreators from './counterActionCreators'
import { bindActionCreators } from 'redux'

function mapStateToProps(state) {
  return { todos: state.todos }
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators(Object.assign({}, todoActionCreators, counterActionCreators), dispatch)
}

export default connect(mapStateToProps, mapDispatchToProps)(TodoApp)
Inject todos of a specific user depending on props
import * as actionCreators from './actionCreators'

function mapStateToProps(state, ownProps) {
  return { todos: state.todos[ownProps.userId] }
}

export default connect(mapStateToProps)(TodoApp)
Inject todos of a specific user depending on props, and inject props.userId into the action
import * as actionCreators from './actionCreators'

function mapStateToProps(state) {
  return { todos: state.todos }
}

function mergeProps(stateProps, dispatchProps, ownProps) {
  return Object.assign({}, ownProps, {
    todos: stateProps.todos[ownProps.userId],
    addTodo: (text) => dispatchProps.addTodo(ownProps.userId, text)
  })
}

export default connect(mapStateToProps, actionCreators, mergeProps)(TodoApp)
Factory functions

Factory functions can be used for performance optimizations

import { addTodo } from './actionCreators'

function mapStateToPropsFactory(initialState, initialProps) {
  const getSomeProperty= createSelector(...);
  const anotherProperty = 200 + initialState[initialProps.another];
  return function(state){
    return {
      anotherProperty,
      someProperty: getSomeProperty(state),
      todos: state.todos
    }
  }
}

function mapDispatchToPropsFactory(initialState, initialProps) {
  function goToSomeLink(){
    initialProps.history.push('some/link');
  }
  return function(dispatch){
    return {
      addTodo
    }
  }
}


export default connect(mapStateToPropsFactory, mapDispatchToPropsFactory)(TodoApp)

connectAdvanced(selectorFactory, [connectOptions])

將一個React組件連接到redux store上去。它是connect()的基礎,但是對于如何將state,props,dispatch結合到最終的props上沒有那么固定的限制。它不會對默認值或結果的記憶做任何假設,而是將這些責任留給調用者。

Arguments

  • selectorFactory(dispatch, factoryOptions): selector(state, ownProps): props (Function)
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 做React需要會什么? react的功能其實很單一,主要負責渲染的功能,現(xiàn)有的框架,比如angular是一個大而...
    蒼都閱讀 14,948評論 1 139
  • 我們已經詳細介紹了Action,Reducer,Store和它們之間的流轉關系。Redux的基礎知識差不多也介紹完...
    張歆琳閱讀 3,873評論 1 17
  • 前言 本文 有配套視頻,可以酌情觀看。 文中內容因各人理解不同,可能會有所偏差,歡迎朋友們聯(lián)系我討論。 文中所有內...
    珍此良辰閱讀 12,168評論 23 111
  • 學習必備要點: 首先弄明白,Redux在使用React開發(fā)應用時,起到什么作用——狀態(tài)集中管理 弄清楚Redux是...
    賀賀v5閱讀 9,066評論 10 58
  • 一、什么情況需要redux? 1、用戶的使用方式復雜 2、不同身份的用戶有不同的使用方式(比如普通用戶和管...
    初晨的筆記閱讀 2,129評論 0 11

友情鏈接更多精彩內容