如果屏幕包裹在 HOC 中,StackNavigator 屏幕的反应导航 header 不会呈现
react navigation header for StackNavigator screen doesn't render if screen wrapped in HOC
总结
- 我创建了一个自定义 HOC,它通过检查 redux 存储是否有 user.id 属性
来检查用户是否已通过身份验证
- 我正在使用 React 导航和 React Native
- 当我将我的屏幕组件包装在我的 HOC 中时,导航 header 出现但消失了(相反,如果我不将我的屏幕组件包装在我的 HOC 中,导航 header出现正确)
- 在 HOC 和包装组件中也有 react-redux connect,我想知道这是否会导致事情中断
当我将屏幕组件包装在我的自定义 HOC 中时,为什么我的反应导航 header 没有正确显示?
我想知道我是否以错误的顺序包装东西——这些是屏幕组件中可能有问题的代码行(我测试时注释掉了其中一个):
// 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
您可以尝试使用 redux 中的 compose
方法。
主要实用程序是
write deeply nested function transformations without the rightward drift of the code
由于connect
需要原始组件,因此
用法
import {compose} from "redux"
const composedWithAuthentication = compose(
connect(mapStateToProps, mapDispatchToProps),
withAuthentication
);
const newWithAuth = composedWithAuthentication(EntityPage)
newWithAuth.navigationOptions = {
// Your Options
}
这会将 navigationOptions
设置在最外层 hoc
或者更简洁的方法是使用 hoistStatics from recompose
export default hoistStatics(composedWithAuthentication)(EntityPage);
Augments a higher-order component so that when used, it copies non-react static properties from the base component to the new component.
总结
- 我创建了一个自定义 HOC,它通过检查 redux 存储是否有 user.id 属性 来检查用户是否已通过身份验证
- 我正在使用 React 导航和 React Native
- 当我将我的屏幕组件包装在我的 HOC 中时,导航 header 出现但消失了(相反,如果我不将我的屏幕组件包装在我的 HOC 中,导航 header出现正确)
- 在 HOC 和包装组件中也有 react-redux connect,我想知道这是否会导致事情中断
当我将屏幕组件包装在我的自定义 HOC 中时,为什么我的反应导航 header 没有正确显示?
我想知道我是否以错误的顺序包装东西——这些是屏幕组件中可能有问题的代码行(我测试时注释掉了其中一个):
// 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
您可以尝试使用 redux 中的 compose
方法。
主要实用程序是
write deeply nested function transformations without the rightward drift of the code
由于connect
需要原始组件,因此
用法
import {compose} from "redux"
const composedWithAuthentication = compose(
connect(mapStateToProps, mapDispatchToProps),
withAuthentication
);
const newWithAuth = composedWithAuthentication(EntityPage)
newWithAuth.navigationOptions = {
// Your Options
}
这会将 navigationOptions
设置在最外层 hoc
或者更简洁的方法是使用 hoistStatics from recompose
export default hoistStatics(composedWithAuthentication)(EntityPage);
Augments a higher-order component so that when used, it copies non-react static properties from the base component to the new component.