UNPKG

core-native

Version:

A lightweight framework based on React Native + Redux + Redux Saga, in strict TypeScript.

110 lines 5.29 kB
import React from "react"; import { AppState } from "react-native"; import { delay, put } from "redux-saga/effects"; import { app } from "../app"; import { errorAction, setStateAction } from "../reducer"; export class ModuleProxy { constructor(module, actions) { this.module = module; this.actions = actions; } getActions() { return this.actions; } attachLifecycle(ComponentType) { var _a; const moduleName = this.module.name; const initialState = this.module.initialState; const lifecycleListener = this.module; const actions = this.actions; return _a = class MainComponent extends React.PureComponent { constructor(props) { super(props); this.onAppStateChange = (nextAppState) => { const { appState } = this.state; if (["inactive", "background"].includes(appState) && nextAppState === "active") { if (lifecycleListener.onAppActive.isLifecycle) { app.store.dispatch(actions.onAppActive()); } } else if (appState === "active" && ["inactive", "background"].includes(nextAppState)) { if (lifecycleListener.onAppInactive.isLifecycle) { app.store.dispatch(actions.onAppInactive()); } } this.setState({ appState: nextAppState }); }; this.state = { appState: AppState.currentState }; this.lifecycleSagaTask = app.sagaMiddleware.run(this.lifecycleSaga.bind(this)); console.info(`Module [${moduleName}] attached component initially rendered`); } componentDidMount() { // According to the document, this API may change soon // Ref: https://facebook.github.io/react-native/docs/appstate#addeventlistener AppState.addEventListener("change", this.onAppStateChange); const props = this.props; if ("navigation" in props) { const navigation = props.navigation; this.focusSubscription = navigation.addListener("didFocus", () => { if (lifecycleListener.onFocus.isLifecycle) { app.store.dispatch(actions.onFocus()); } }); this.blurSubscription = navigation.addListener("willBlur", () => { if (lifecycleListener.onBlur.isLifecycle) { app.store.dispatch(actions.onBlur()); } }); } } componentWillUnmount() { if (lifecycleListener.onDestroy.isLifecycle) { app.store.dispatch(actions.onDestroy()); } if (this.blurSubscription) { this.blurSubscription.remove(); } if (this.focusSubscription) { this.focusSubscription.remove(); } this.lifecycleSagaTask.cancel(); app.store.dispatch(setStateAction(moduleName, initialState, `@@${moduleName}/@@reset`)); AppState.removeEventListener("change", this.onAppStateChange); console.info(`Module [${moduleName}] attached component destroyed`); } *lifecycleSaga() { const props = this.props; if (lifecycleListener.onEnter.isLifecycle) { if ("navigation" in props && "state" in props.navigation) { yield* runSafely(lifecycleListener.onEnter.bind(lifecycleListener), props.navigation.state.params, props.navigation.state.path); } else { yield* runSafely(lifecycleListener.onEnter.bind(lifecycleListener), {}, null); } } if (lifecycleListener.onTick.isLifecycle) { const tickIntervalInMillisecond = (lifecycleListener.onTick.tickInterval || 5) * 1000; const boundTicker = lifecycleListener.onTick.bind(lifecycleListener); while (true) { yield* runSafely(boundTicker); yield delay(tickIntervalInMillisecond); } } } render() { return <ComponentType {...this.props}/>; } }, _a.displayName = `ModuleBoundary(${moduleName})`, _a; } } function* runSafely(handler, ...payload) { try { yield* handler(...payload); } catch (error) { yield put(errorAction(error)); } } //# sourceMappingURL=ModuleProxy.js.map