React Navigation源代码阅读 : views/withNavigationFocus.js

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);
}

猜你喜欢

转载自blog.csdn.net/andy_zhang2007/article/details/80381046
今日推荐