【问题标题】:Reducing React-Redux state & dispatch boilerplate减少 React-Redux 状态和调度样板
【发布时间】:2019-01-16 18:14:52
【问题描述】:

我通常使用以下模式构建组件:

import selectors from '../store/selectors'
import someAction1 from '../actions/someAction1'
import someAction2 from '../actions/someAction2'
import someAction3 from '../actions/someAction3'

class MyComponent extends React.Component {
  render() => {
    return <Fragment>
      <div>{this.props.someReduxProperty1}</div>
      <div>{this.props.someReduxProperty2}</div>
      <div>{this.props.someReduxProperty3}</div>
      <a onClick={this.props.someAction1}>Action1</a>
      <a onClick={this.props.someAction2}>Action2</a>
      <a onClick={this.props.someAction3}>Action3</a> 
    </Fragment>
  }
}

export default connect(
  (state, ownProps) => {
    return {
      someReduxProperty1: selectors.getSomeReduxProperty1(state),
      someReduxProperty2: selectors.getSomeReduxProperty2(state),
      someReduxProperty3: selectors.getSomeReduxProperty3(state)
    }
  },
  (dispatch) => {
    return {
      someAction1: () => {
        dispatch(someAction1())
      },
      someAction2: () => {
        dispatch(someAction2())
      },
      someAction3: () => {
        dispatch(someAction3())
      }
    }
  }
)(MyComponent)

这确实完成了工作,但感觉就像我在重复输入相同的内容,即使在这个微不足道的简短示例中也是如此。我的容器组件在它们起作用时感觉非常冗长。此外,我发现我经常修改组件中使用的属性和操作列表,这使得不断地重新输入它有点令人沮丧。我读到的大多数关于 react+redux 的例子似乎都反映了这个代码设置。

这真的有必要吗?我正在考虑忽略似乎是 React+Redux 最佳实践的东西,只是通过 statedispatch 作为我组件的道具:

import selectors from '../store/selectors'
import someAction1 from '../actions/someAction1'
import someAction2 from '../actions/someAction2'
import someAction3 from '../actions/someAction3'

class MyComponent extends React.Component {
  render() => {
    const { state, dispatch } = this.props
    return <Fragment>
      <div>{selectors.getSomeReduxProperty1(state)}</div>
      <div>{selectors.getSomeReduxProperty2(state)}</div>
      <div>{selectors.getSomeReduxProperty3(state)}</div>
      <a onClick={() => { dispatch(someAction1()) }}>Action1</a>
      <a onClick={() => { dispatch(someAction2()) }}>Action2</a>
      <a onClick={() => { dispatch(someAction3()) }}>Action3</a>
    </Fragment>
  }
}

export default connect(
  (state, ownProps) => {
    return { state: state }
  }
  /* dispatch gets added by default */
)(MyComponent)

代码中只有最少的变量名重复。额外的好处是,由于每个组件的连接调用都是相同的,我可以连接一个助手并进一步缩短我的组件:

export default connectHelper = (componentClass) => {
  return connect((state) => {
    return { state: state }
  })(componentClass)
}
class MyComponent extends React.Component {
  ...
}

export default connectHelper(MyComponent)

通过浏览connect 调用,我确实失去了一些能力,无法一目了然地查看我的 Redux 商店中使用了哪些属性。我没问题。

所以我的问题是:

  1. 是否有任何其他考虑因素需要我在本质上绕过 mapStatetoProps 进行牺牲?我担心的一个问题是,由于只有一个 state 属性,因此 React 可能会在每次 Redux 存储中的任何属性发生更改时过度地重新渲染每个组件。这就是为什么需要在 mapStateToProps 中手动映射属性的原因吗?

  2. 跳过 mapDispatchToProps 并使用默认注入的 this.props.dispatch 我会失去什么?我必须做“额外”的工作才能直接在 mapDispatchToProps 中映射状态;我能从这项努力中得到什么?

  3. 是否有其他代码组织/模式有助于减少 React+Redux 设置中的组件属性混乱?

谢谢!只是让我的头脑围绕这些工具。这是一个有趣的练习,但有些事情感觉有点古怪!

【问题讨论】:

    标签: javascript reactjs redux react-redux


    【解决方案1】:

    是的,有很多方法可以缩短它。

    首先,您应该使用the "object shorthand" form of mapDispatch

    const mapDispatch = {
        someAction1,
        someAction2,
        someAction3,
    };
    

    其次,虽然我们没有与 mapState 等效的“对象速记”,但您可以使用 Reselect 的 createStructuredSelector API 来做同样的事情。

    是的,如果您传递整个 state 值,您的组件现在将针对 Redux 存储的每次更新重新渲染。 React-Redux does a lot of work internally to make sure your own component only re-renders when needed,这是基于您的 mapState 函数返回的值。

    第三,考虑在组件的开头使用解构来提取他们需要的特定道具,这样你就不会在每一行都重复this.props.。这可以是类组件的render() 方法中的对象解构,也可以是函数组件的函数参数解构。

    最后,虽然它不是特定于 React 的,但请查看我们的新 redux-starter-kit package。它包括用于简化几个常见 Redux 用例的实用程序,包括存储设置、定义 reducer、不可变更新逻辑、检查意外突变,甚至自动创建整个状态“切片”,而无需手动编写任何动作类型或动作创建者。

    【讨论】:

    猜你喜欢
    • 2020-03-31
    • 2016-09-22
    • 1970-01-01
    • 2022-01-03
    • 1970-01-01
    • 1970-01-01
    • 2020-03-27
    • 1970-01-01
    • 2021-01-16
    相关资源
    最近更新 更多