import React from 'react';
import propTypes from 'prop-types';
import hoistStatics from 'hoist-non-react-statics';
import invariant from '../utils/invariant';
// HOC,增强一个组件,让其具有 navigation 属性和 isFocused 属性
export default function withNavigationFocus(Component) {
class ComponentWithNavigationFocus extends React.Component {
static displayName = `withNavigationFocus(${Component.displayName ||
Component.name})`;
static contextTypes = {
navigation: propTypes.object.isRequired,
};
constructor(props, context) {
super();
// 初始化判断该组件是否是当前屏幕并记录到 isFocused
this.state = {
isFocused: this.getNavigation(props, context).isFocused(),
};
}
componentDidMount() {
// 增加当前组件对屏幕切换事件的监听器,
// 每当该组件被聚焦为当前屏幕或者被退出当前屏幕时,相应地修改 isFocused
const navigation = this.getNavigation();
this.subscriptions = [
navigation.addListener('didFocus', () =>
this.setState({isFocused: true})
),
navigation.addListener('willBlur', () =>
this.setState({isFocused: false})
),
];
}
componentWillUnmount() {
this.subscriptions.forEach(sub => sub.remove());
}
getNavigation = (props = this.props, context = this.context) => {
const navigation = props.navigation || context.navigation;
invariant(
!!navigation,
'withNavigationFocus can only be used on a view hierarchy of a navigator. The wrapped component is unable to get access to navigation from props or context.'
);
return navigation;
};
render() {
return (
<Component
{...this.props}
isFocused={this.state.isFocused}
ref={this.props.onRef}
/>
);
}
}
// 静态方法复制, 源组件 Component 的静态方法复制到 容器组件 ComponentWithNavigationFocus 上面
return hoistStatics(ComponentWithNavigationFocus, Component);
}
React Navigation源代码阅读 : views/withNavigationFocus.js
猜你喜欢
转载自blog.csdn.net/andy_zhang2007/article/details/80381046
今日推荐
周排行