rn-collie
Version: 
A UI library for react native.
118 lines (107 loc) • 3.17 kB
JavaScript
/**
 * @format
 */
import React, {Component, PureComponent} from "react";
import {DeviceEventEmitter, View} from 'react-native';
import LayerEntity from "./LayerEntity";
export const addLayer: string = 'addLayer';
export const updateLayer: string = 'updateLayer';
export const removeLayer: string = 'removeLayer';
type State = {
    //弹出层组件数组
    layers: Array<LayerEntity>,
}
/**
 * 管理所有的layer
 * 通常不需要直接用它,而使用LayerEntity来操作
 * 作为layer层的父组件
 * 适用layer有关的组件,需要在根部的view上包裹LayerManager
 * demo:
 * <LayerManager>
 *     <RootView/>
 * </LayerManager>
 */
export default class LayerManager extends Component<any, State> {
    constructor(props) {
        super(props);
        this.state = {
            layers: [],
        };
    }
    componentDidMount() {
        DeviceEventEmitter.addListener(addLayer, (layerEntity) => this.add(layerEntity));
        DeviceEventEmitter.addListener(updateLayer, (layerEntity, data) => this.update(layerEntity, data));
        DeviceEventEmitter.addListener(removeLayer, (layerEntity) => this.remove(layerEntity));
    }
    /**
     * 栈底时取消事件监听
     * 让栈底组件移出自身引用
     */
    componentWillUnmount() {
        DeviceEventEmitter.removeAllListeners(addLayer);
        DeviceEventEmitter.removeAllListeners(updateLayer);
        DeviceEventEmitter.removeAllListeners(removeLayer);
    }
    /**
     * 添加弹出层组件
     * @param layerEntity
     */
    add(layerEntity: LayerEntity) {
        let {layers} = this.state;
        if (layers.indexOf(layerEntity) < -1) {
            throw new Error('LayerEntity instance can only be added once');
        }
        layers.push(layerEntity);
        this.setState({layers});
        return layerEntity;
    }
    /**
     *更新layer的状态
     * @param layerEntity
     * @param data 状态
     */
    update(layerEntity: LayerEntity, data: {} = {}) {
        let layers: Array<LayerEntity> = this.state.layers;
        let isHit = layers.indexOf(layerEntity) > -1;
        if (isHit) {
            layerEntity._onUpdate(data);
        }
    }
    /**
     * 移出弹出层组件
     * @param layerEntity
     */
    remove(layerEntity: LayerEntity) {
        let {layers} = this.state;
        for (let i = layers.length - 1; i >= 0; --i) {
            if (layers[i] === layerEntity) {
                layers.splice(i, 1);
                this.setState({layers});
                break;
            }
        }
    }
    render() {
        let layers = this.state.layers;
        return (
            <View style={{flex: 1}}>
                <RealDom>
                    {this.props.children}
                </RealDom>
                {layers.map((item: LayerEntity, index: number) => item._createLayer(index))}
            </View>
        );
    }
}
/**
 * 渲染真实的dom,弹出层弹出不能让真实的dom刷新,故pure
 */
class RealDom extends PureComponent {
    render() {
        return (
            <View style={{flex: 1}}>
                {this.props.children}
            </View>
        );
    }
}