【问题标题】:react navigation header for StackNavigator screen doesn't render if screen wrapped in HOC如果屏幕包裹在 HOC 中,则 StackNavigator 屏幕的反应导航标题不会呈现
【发布时间】:2018-04-13 21:24:30
【问题描述】:

总结

  1. 我创建了一个自定义 HOC,通过检查 redux 存储是否具有 user.id 属性来检查用户是否经过身份验证
  2. 我正在使用反应导航和反应原生
  3. 当我将屏幕组件包装到 HOC 中时,导航标题会出现但被空白(相反,如果我不将屏幕组件包装到 HOC 中,导航标题会正确显示)
  4. 在 HOC 和被包装的组件中也有 react-redux 连接,我想知道这是否会让事情崩溃

当我将屏幕组件包装在自定义 HOC 中时,为什么我的反应导航标题没有正确显示?

我想知道我是否以错误的顺序包装东西——这些是屏幕组件中可能有问题的代码行(在我测试时,其中一个被注释掉了):

// export default connect(mapStateToProps, mapDispatchToProps)(EntityPage); <--this renders the header fine

  export default connect(mapStateToProps, mapDispatchToProps)(withAuthentication(EntityPage)); <--this renders the header blank

代码

我做的自定义 HOC 检查身份验证

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;

我用自定义身份验证 HOC 包装的屏幕组件

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

【问题讨论】:

    标签: reactjs react-native stack react-navigation


    【解决方案1】:

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

    编写深度嵌套的函数转换,避免代码向右漂移

    由于 connect 因此需要一个原始组件,

    用法

    import {compose} from "redux"
    
    const composedWithAuthentication = compose(
        connect(mapStateToProps, mapDispatchToProps),
        withAuthentication
    );
    
    const newWithAuth = composedWithAuthentication(EntityPage)
    
    newWithAuth.navigationOptions = {
     // Your Options
    }
    

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

    或者更简洁的方法是使用来自recomposehoistStatics

    export default hoistStatics(composedWithAuthentication)(EntityPage);
    

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

    【讨论】:

    • 谢谢!我做了你所说的,它给了我一个关于函数作为 React 孩子无效的错误。然后我将导出行修改为export default composedWithAuthentication(ScreenComponent); 页面呈现(和以前一样)但反应导航标题仍然是空白
    • 你先生是个天才!感谢您的帮助@Pritish Vaidya
    • 请注意,如果您想使用导航道具或其他东西,请分配一个将对象返回给导航选项的函数newWithAuth.navigationOptions = ({navigation}) =&gt; { return { title: 'My Page', headerRight: ( &lt;Button type='action' title='Add Entity' onPress={()=&gt;navigation.navigate('EntityCreate')}&gt; &lt;/Button&gt;), }; };
    • 是的,我还检查了另一个避免这种情况的实用程序。在答案中更新。
    • 刚刚更新为使用recompose 库中的hoistStatics,它使事情更清晰/更易于阅读。不必将静态导航声明移至文件底部。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多