首页 > 解决方案 > next.js mapStateToProps、mapDispatchToProps 和 getInitialProps

问题描述

在使用 next.js 时,我目前仍在尝试围绕 redux 进行思考,但我不确定将 redux 与 next.js 一起使用的最佳方法是什么。我习惯于将 mapDispatchToProps 用于我的操作,并将 mapStateToProps 用于我的道具。经过一些研究,我现在在我的 _app.js 中使用 next-redux-wrapper,就像推荐的那样,但现在我正在努力解决如何最好地获取我的道具并调度我的动作。我查看了一些示例和实践,现在有一个基于这些示例之一的计数器组件。

class Counter extends Component {
  increment = () => {
    const {dispatch} = this.props
    dispatch(incrementCount())
  }

  decrement = () => {
    const {dispatch} = this.props
    dispatch(decrementCount())
  }

  reset = () => {
    const {dispatch} = this.props
    dispatch(resetCount())
  }

  render () {
    const { count } = this.props
    return (
      <div>
        <h1>Count: <span>{count}</span></h1>
        <button onClick={this.increment}>+1</button>
        <button onClick={this.decrement}>-1</button>
        <button onClick={this.reset}>Reset</button>
      </div>
    )
  }
}

function mapStateToProps (state) {
  const {count} = state.counter;
  return {count};
}

export default connect(mapStateToProps)(Counter)

到目前为止,我看到的大多数示例都执行与此类似的操作,或者仅在 getInitialProps 中调度操作。是否有理由这样做而不使用 mapDispatchToProps?

因为这项工作也很好:

export default connect(null, {authenticate})(Signin);

在 getIntialProps 中调度动作似乎有一些缺点(或者我犯了一些错误),因为当道具改变时它们不会再次执行。在我的用户配置文件组件中,我根据来自 redux 商店的令牌获取当前用户,如下所示:

const Whoami = ({isAuthenticated, user}) => (
  <Layout title="Who Am I">
    {(isAuthenticated && user && <h3 className="title is-3">You are logged in as <strong className="is-size-2 has-text-primary">{user}</strong>.</h3>) ||
      <h3 className="title is-3 has-text-danger ">You are not authenticated.</h3>}
  </Layout>
);

Whoami.getInitialProps = async function (ctx) {
  initialize(ctx);

  const token = ctx.store.getState().auth.token;
  if(token) {
    const response = await axios.get(`${API}/user`, {headers: {
      authorization: token
    }});
    const user = response.data.user;
    return {
      user
    };
  }
    }

const mapStateToProps = (state) => (
  {isAuthenticated: !!state.auth.token}
);

export default connect(mapStateToProps)(Whoami);

这对于初始页面加载或在客户端导航时非常有效,但是当令牌过期或我注销时,如果没有重新加载或在没有我的 mapStateToProps 的情况下再次导航,页面不会反映这一点。但是将关注点拆分为 2 个单独的功能似乎非常笨拙。但我找不到更清洁的方法来做到这一点。

提前致谢

标签: reactjsreduxreact-reduxnext.js

解决方案


关于mapDispatchToProps

mapDispatchToProps至少最好使用它,因为它更容易测试:您可以将模拟函数传递给您的组件。使用this.props.dispatch来调度一些导入的动作可能会更难。

关于getInitialProps

这个答案可能会有所帮助:

GetInitialProps:由 Next.js 提供,它并不总是被触发,所以要小心,当你将一个组件包装在另一个组件中时会发生这种情况。如果父组件有 GetInitialProps,则永远不会触发子组件的 GetInitialProps,请参阅此线程了解更多信息。


推荐阅读