-
Notifications
You must be signed in to change notification settings - Fork 1
/
react.js
65 lines (57 loc) · 1.78 KB
/
react.js
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
/**
* React integration for Normas
*
* @see {@link https://github.com/evrone/normas#reactjs-integration|Docs}
* @see {@link https://github.com/evrone/normas/blob/master/src/js/extensions/react.js|Source}
* @license MIT
* @copyright Dmitry Karpunin <koderfunk@gmail.com>, 2017-2018
*/
const defaultOptions = {
selector: '[data-react-component]',
listenOptions: {},
};
export default {
normas: null,
React: null,
ReactDOM: null,
PropTypes: null,
components: {},
init({ normas, app, React, ReactDOM, PropTypes }, options = {}) {
const { selector, listenOptions } = normas.helpers.deepMerge(defaultOptions, options);
this.normas = normas || app;
this.React = React;
this.ReactDOM = ReactDOM;
this.PropTypes = PropTypes;
normas.listenToElement(
selector,
this.mountComponentToElement.bind(this),
this.unmountComponentFromElement.bind(this),
listenOptions,
);
},
registerComponents(components) {
Object.assign(this.components, components);
},
// private
mountComponentToElement($element) {
const domNode = $element[0];
const name = domNode.getAttribute('data-react-component');
if (!name) {
this.normas.error('No component name in', domNode);
return;
}
const componentClass = this.components[name];
if (!componentClass) {
this.normas.error('No registered component class with name', name);
return;
}
const propsString = domNode.getAttribute('data-props');
const props = propsString ? JSON.parse(propsString) : null;
const component = this.React.createElement(componentClass, props);
this.ReactDOM.render(component, domNode);
},
unmountComponentFromElement($element) {
const domNode = $element[0];
this.ReactDOM.unmountComponentAtNode(domNode);
},
}