如果屏幕包裹在HOC

时间:2018-04-13 21:24:31

标签: reactjs react-native stack react-navigation

摘要

  1. 我创建了一个自定义HOC,通过检查redux存储是否具有user.id属性来检查正在进行身份验证的用户
  2. 我正在使用反应导航并做出反应原生
  3. 当我将我的屏幕组件包裹在我的HOC中时,导航标题会出现但是已被消隐(相反,如果我不想将我的屏幕组件包裹在我的HOC中,导航标题会正确显示)
  4. 在HOC和包裹组件的混合物中也有react-redux连接,我想知道这是否会使事情破裂
  5. 当我在自定义HOC中包装屏幕组件时,为什么我的反应导航标题显示不正确?

    我想知道我是否以错误的顺序包装东西 - 这些是来自屏幕组件的可能违规的代码行(当我测试时,一个或另一个被注释掉):

    
    
    // export default connect(mapStateToProps, mapDispatchToProps)(EntityPage); <--this renders the header fine
    
      export default connect(mapStateToProps, mapDispatchToProps)(withAuthentication(EntityPage)); <--this renders the header blank
    &#13;
    &#13;
    &#13;

    代码

    自定义HOC我检查了身份验证

    &#13;
    &#13;
    import React, {
      Component
    } from 'react';
    import PropTypes from 'prop-types';
    import {
      Alert
    } from 'react-native';
    import {
      connect
    } from 'react-redux';
    
    function withAuthentication(Comp) {
      class AuthenticatedScreen extends Component {
        componentDidUpdate(prevProps) {
          if (this.props.user && !this.props.user.id) {
            Alert.alert('you\'re not logged in anymore');
          }
        }
    
        render() {
          return <Comp { ...this.props
          }
          />;
        }
      }
    
      function mapStateToProps(state) {
        return {
          user: state.user,
        };
      }
    
      AuthenticatedScreen.propTypes = {
        user: PropTypes.object,
        component: PropTypes.object,
      };
    
      return connect(mapStateToProps)(AuthenticatedScreen);
    }
    
    export default withAuthentication;
    &#13;
    &#13;
    &#13;

    我使用自定义身份验证HOC

    打包的屏幕组件

    &#13;
    &#13;
    import withAuthentication from '../User/AuthorizedHOC'; <--my custom HOC import
    
    class EntityPage extends Component {
        static navigationOptions = ({navigation}) => {
          return {
            title: 'My Entities',
            headerRight: (
    >>        <Button type='action' title='Add New Entity' onPress={()=>navigation.navigate('EntityCreate')}>
              </Button>),
            headerStyle: {paddingRight: (Platform.OS === 'ios') ? 0 : 8},
          };
        };
    
        componentDidMount() {
          this.props.loadEntities();
        }
    
        render() {
          const {
            entities,
          } = this.props;
    
          return (
            <FullscreenView>
              <EntityList entities={entities}/>
            </FullscreenView>
          );
        }
      }
    
      function mapStateToProps(state) {
        return {
          entities: getSortedEntityList(state),
            };
      }
    
      function mapDispatchToProps(dispatch) {
        return {
          loadEntities: () => dispatch(loadEntities()),
          deleteEntity: (entity) => dispatch(deleteEntity(entity)),
        };
      }
    
      // export default connect(mapStateToProps, mapDispatchToProps)(EntityPage); <--this renders the header fine
    
      export default connect(mapStateToProps, mapDispatchToProps)(withAuthentication(EntityPage)); <--this renders the header blank
    &#13;
    &#13;
    &#13;

1 个答案:

答案 0 :(得分:2)

您可以尝试使用redux中的compose方法。 主要用途是

  

编写深层嵌套的函数转换,而不会使代码向右漂移

因为connect因此需要原始组件,

<强>用法

import {compose} from "redux"

const composedWithAuthentication = compose(
    connect(mapStateToProps, mapDispatchToProps),
    withAuthentication
);

const newWithAuth = composedWithAuthentication(EntityPage)

newWithAuth.navigationOptions = {
 // Your Options
}

这会将navigationOptions设置在最外面的hoc

或更简洁的方法是使用hoistStatics

中的recompose
export default hoistStatics(composedWithAuthentication)(EntityPage);
  

增加高阶组件,以便在使用时将非反应静态属性基本组件复制到新组件