React-Redux

react-redux文档翻译

2017-10-29  本文已影响0人  txwslyf

英文文档链接

API


<Provider store>

使得层级之下的组件可以通过connect()函数访问到Redux store。通常,如果你不将父组件或者根组件用<Provider>组件包裹起来的话,你是不可以使用connect()函数的。

Props

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的一层包装,对外提供了一套对于大多数开发情况下方便的API。
它并不更改传入的组件,而是返回一个新的、连接到store的组件共你使用。

Arguments

mapStateToProps和mapDispatchToProps函数的元数(arity,可以理解为函数长度)决定了它们是否能接收到ownProps作为第二个参数。

注意:如果定义一个包含强制性参数函数(这个函数的长度为 1)时,ownProps不会传到 mapStateToPropsmapDispatchToProps 中。举个例子,如下这样定义一个函数时将不会接收到 ownProps 作为第二个参数。

function mapStateToProps(state) {
  console.log(state); // state
  console.log(arguments[1]); // undefined
}
//因为这个函数有一个参数有默认值,所以这个函数的长度仍然为1
const mapStateToProps = (state, ownProps = {}) => {
  console.log(state); // state
  console.log(ownProps); // undefined
}

当函数没有强制性的参数或两个参数时将接收到 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(优化) connect when options.pure is true

options.puretrue的时候,connect将执行几个相等检测,以此避免不必要的mapStateToProps, mapDispatchToProps, mergeProps调用,最终导致render()。这些相等检测包括areStatesEqual, areOwnPropsEqual, areStatePropsEqual, 和areMergedPropsEqual。尽管默认参数可能适合于99%的场景,但是出于性能或者其他原因,你也许像自定义它们的实现,下面是几个例子。

返回值

根据配置信息,返回一个注入了 state 和 action creator 的 React高阶组件。这个组件是由connectAdvanced创建的。

例子

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()的基础,但是对于如何将statepropsdispatch结合到最终的props上没有那么固定的限制。它不会对默认值或结果的记忆做任何假设,而是将这些责任留给调用者。

Arguments

上一篇下一篇

猜你喜欢

热点阅读