Reactjs 反应:如何用HOC包装组件?(跨组件访问登录属性)

Reactjs 反应:如何用HOC包装组件?(跨组件访问登录属性),reactjs,redux,react-router,higher-order-functions,higher-order-components,Reactjs,Redux,React Router,Higher Order Functions,Higher Order Components,我有一个react(使用redux和react router)应用程序,它需要根据商店中某些数据的状态以及与商店中数据相关的一系列其他内容,在不同的点上了解用户是否登录 为了实现这一点,我创建了一个高阶组件,如下所示: import React from 'react'; import {connect} from 'react-redux'; export function masterComponent(Component){ class MasterComponent extend

我有一个react(使用redux和react router)应用程序,它需要根据商店中某些数据的状态以及与商店中数据相关的一系列其他内容,在不同的点上了解用户是否登录

为了实现这一点,我创建了一个高阶组件,如下所示:

import React from 'react';
import {connect} from 'react-redux';

export function masterComponent(Component){

  class MasterComponent extends React.Component {

    constructor(props){
      super(props);
    }

    loggedIn(){
      return this.props.player.token? true : false
    }

    render(){
      return (
        <Component {...this.props} player={{loggedIn: this.loggedIn()}}/>
      );
    }
  }

  UserComponent.propTypes = {
    player: React.PropTypes.object
  };


  function mapStateToProps(state) {
    return state;
  }

  return connect(
    mapStateToProps
  )(MasterComponent);

}

有更好的方法吗?

这取决于您的用例,我看到了3种可能的解决方案。下面的代码未经测试,是半伪代码

你最初的提议,重构 在任何你可以使用的组件中

loginService.getPlayer() 
验证是否有人已登录

缺点与您的方法相比:如果操作
'ADD\u CREDENTIALS'
已被调度,但请求
loginService.getPlayer()
的组件没有得到重新请求/更新,则您可能会得到不一致的状态。我相信您可以通过更具体的应用程序知识来解决这个问题

上下文(我最不喜欢的) 使用React并将所需属性传递给所有其他组件

export function masterComponent(Component) {

  const MasterComponent = (props) => {
    const loggedIn = props.player.token? true : false;

    // initial solution would override player, so you need 
    // something like this
    const player = { 
      ...this.props.player,
      loggedIn,
    };

    return <Component {...this.props} player={player} />
  }

  // Important! Here is the crucial part of the refactoring, 
  // not the coding style changes. Map only the relevant 
  // state properties, otherwise the component would rerender 
  // whenever any state property changed. 
  return connect(state => ({ player: this.state.player }))(MasterComponent);
}
function loginMiddleware() {
  return store => next => action => {
    if (action.type === 'ADD_CREDENTIALS') {
      const { player } = store.getState();
      loginService.setPlayer(player);
    }

    // removePlayer if action.type === 'LOGOUT';

    return next(action);
  }
}
loginService.getPlayer()