UNPKG

rn-collie

Version:

A UI library for react native.

118 lines (107 loc) 3.17 kB
/** * @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> ); } }