blog icon indicating copy to clipboard operation
blog copied to clipboard

mapStateToProps 笔记

Open le0zh opened this issue 5 years ago • 0 comments

mapStateToProps

(state, ownProps?) => Object | Function

概况

如果指定了 mapStateToProps,那么被包裹的组件就会订阅 Redux Store 的更新,就是说每次 store 更新后, mapStateToProps 就会被调用。该方法的结果必须是个普通对象,这个对象将会被合并到被包裹组件的属性中。如果不想订阅 store 的更新,必须要在需要指定 mapStateToProps 的地方传一个 null 或者 undefined。

参数

该方法最多有两个参数(第一个 state 是必须的,第二个是可选的),传递的参数个数不一样,则表现也有所差别。

  1. 如果只有第一个参数
const mapStateToProps = state => ({ todos: state.todos })

则将会在 store 发生变化后被调用,并只有一个 state 作为参数。

  1. 如果有两个参数
const mapStateToProps = (state, ownProps) => ({
  todo: state.todos[ownProps.id]
})

如果有两个参数,则除了 state 变化外,父组件属性更新(基于 shallow 比较)后也会被调用,第二个参数(常被称为 ownProps)可以拿到当前组件的属性。

返回值

mapStateToProps 一般被期望返回一个普通对象(常被称为 stateProps),这个对象将被合并到被包裹组件的属性中。

如果指定了 mergePropsconnect 方法的第三个参数),这个对象将被作为 mergeProps 方法的第一个参数。

mapStateToProps 的返回结果决定了被连接的组件是否重新渲染。

注意,mapStateToProps 也能返回一个函数(工厂方法)。 这个方法将会在组件每次实例化时被调用一次。 同时工厂方法的返回值将作为真正的 mapStateToProps。 工厂方法常常用于 memoized selector,提供了组件实例粒度的 selectors。

const makeUniqueSelectorInstance = () =>
  createSelector(
    [selectItems, selectItemId],
    (items, itemId) => items[itemId]
  )

const makeMapState = state => {
  const selectItemForThisComponent = makeUniqueSelectorInstance()
  return function realMapState(state, ownProps) {
    const item = selectItemForThisComponent(state, ownProps.itemId)
    return { item }
  }
}
export default connect(makeMapState)(SomeComponent)

le0zh avatar Sep 05 '19 04:09 le0zh