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);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值