-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathModule.tsx
91 lines (73 loc) · 1.99 KB
/
Module.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import * as React from 'react'
import * as PropTypes from 'prop-types'
import { Reducer } from 'redux'
import { DynamicStore } from './createStore'
type ReactComponent = React.ComponentType<any>
interface ModuleShape {
name?: string
reducers?: { [key: string]: Reducer }
view?: ReactComponent
}
interface State {
module?: ModuleShape
}
interface Import {
default: ModuleShape
}
const defaultModuleProps = {
loading: '',
}
const initialState = {
module: undefined,
}
type DefaultModuleProps = Readonly<typeof defaultModuleProps>
type ModuleProps = {
resolve: () => Promise<Import>
loading?: string | ReactComponent
}
type Context = {
store: DynamicStore
}
class Module extends React.Component<any, State> {
static contextTypes = {
store: PropTypes.object,
}
_isMounted: boolean = false
readonly context: Context
readonly state: State = initialState
readonly defaultModuleProps: DefaultModuleProps = defaultModuleProps
async componentDidMount() {
this._isMounted = true
try {
const { resolve } = this.props
const { default: module } = await resolve()
const { name, reducers } = module
const { store } = this.context
if (name && store && reducers) store.addModule({ name, reducers })
this._isMounted && this.setState({ module })
} catch (error) {
throw error
}
}
componentWillUnmount() {
const { module } = this.state
const { store } = this.context
if (store && module != null && module.name != null) {
store.removeModule(module.name)
}
this._isMounted = false
}
render() {
const { module } = this.state
const { loading, resolve, ...rest } = this.props
if (module === undefined)
return <React.Fragment>{this.props.loading}</React.Fragment>
if (module && module.view != null)
return React.createElement(module.view, rest)
return null
}
}
const WithModuleProps = <P extends {}>(props: ModuleProps & P) => (
<Module {...props} />
)
export default WithModuleProps