-
-
Notifications
You must be signed in to change notification settings - Fork 631
/
ReactOnRails.js
214 lines (185 loc) · 6.04 KB
/
ReactOnRails.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
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
import * as ClientStartup from './clientStartup';
import handleError from './handleError';
import ComponentRegistry from './ComponentRegistry';
import StoreRegistry from './StoreRegistry';
import serverRenderReactComponent from './serverRenderReactComponent';
import buildConsoleReplay from './buildConsoleReplay';
import createReactElement from './createReactElement';
import ReactDOM from 'react-dom';
import context from './context';
const ctx = context();
const DEFAULT_OPTIONS = {
traceTurbolinks: false,
};
ctx.ReactOnRails = {
/**
* Main entry point to using the react-on-rails npm package. This is how Rails will be able to
* find you components for rendering.
* @param components (key is component name, value is component)
*/
register(components) {
ComponentRegistry.register(components);
},
/**
* Allows registration of store generators to be used by multiple react components on one Rails
* view. store generators are functions that take one arg, props, and return a store. Note that
* the setStore API is different in tha it's the actual store hydrated with props.
* @param stores (keys are store names, values are the store generators)
*/
registerStore(stores) {
if (!stores) {
throw new Error(`Called ReactOnRails.registerStores with a null or undefined, rather than ` +
`an Object with keys being the store names and the values are the store generators.`);
}
StoreRegistry.register(stores);
},
/**
* Allows retrieval of the store by name. This store will be hydrated by any Rails form props.
* Pass optional param throwIfMissing = false if you want to use this call to get back null if the
* store with name is not registered.
* @param name
* @param throwIfMissing Defaults to true. Set to false to have this call return undefined if
* there is no store with the given name.
* @returns Redux Store, possibly hydrated
*/
getStore(name, throwIfMissing = true) {
return StoreRegistry.getStore(name, throwIfMissing);
},
/**
* Set options for ReactOnRails, typically before you call ReactOnRails.register
* Available Options:
* `traceTurbolinks: true|false Gives you debugging messages on Turbolinks events
*/
setOptions(options) {
if (options.hasOwnProperty('traceTurbolinks')) {
this._options.traceTurbolinks = options.traceTurbolinks;
delete options.traceTurbolinks;
}
if (Object.keys(options).length > 0) {
throw new Error('Invalid options passed to ReactOnRails.options: ', JSON.stringify(options));
}
},
reactOnRailsPageLoaded() {
ClientStartup.reactOnRailsPageLoaded();
},
/**
* Returns CFRS authenticity token inserted by Rails csrf_meta_tags
* @returns String or null
*/
getAuthenticityToken() {
/*const token = _.find(document.querySelectorAll('meta'), ['name', 'csrf-token']);*/
const token = document.querySelector('meta[name="csrf-token"]');
return token ? token.content : null;
},
/**
* Returns header with csrf authenticity token
* @param options
* @returns {*}
*/
authenticityHeader(options) {
options = options || {};
return Object.assign(options, {
'X-CSRF-Token': ReactOnRails.getAuthenticityToken(),
'X-Requested-With': 'XMLHttpRequest'
});
},
////////////////////////////////////////////////////////////////////////////////
// INTERNALLY USED APIs
////////////////////////////////////////////////////////////////////////////////
/**
* Retrieve an option by key.
* @param key
* @returns option value
*/
option(key) {
return this._options[key];
},
/**
* Allows retrieval of the store generator by name. This is used internally by ReactOnRails after
* a rails form loads to prepare stores.
* @param name
* @returns Redux Store generator function
*/
getStoreGenerator(name) {
return StoreRegistry.getStoreGenerator(name);
},
/**
* Allows saving the store populated by Rails form props. Used internally by ReactOnRails.
* @param name
* @returns Redux Store, possibly hydrated
*/
setStore(name, store) {
return StoreRegistry.setStore(name, store);
},
/**
* ReactOnRails.render("HelloWorldApp", {name: "Stranger"}, 'app');
*
* Does this:
* ReactDOM.render(React.createElement(HelloWorldApp, {name: "Stranger"}),
* document.getElementById('app'))
*
* @param name Name of your registered component
* @param props Props to pass to your component
* @param domNodeId
* @returns {virtualDomElement} Reference to your component's backing instance
*/
render(name, props, domNodeId) {
const reactElement = createReactElement({ name, props, domNodeId });
return ReactDOM.render(reactElement, document.getElementById(domNodeId));
},
/**
* Get the component that you registered
* @param name
* @returns {name, component, generatorFunction}
*/
getComponent(name) {
return ComponentRegistry.get(name);
},
/**
* Used by server rendering by Rails
* @param options
*/
serverRenderReactComponent(options) {
return serverRenderReactComponent(options);
},
/**
* Used by Rails to catch errors in rendering
* @param options
*/
handleError(options) {
return handleError(options);
},
/**
* Used by Rails server rendering to replay console messages.
*/
buildConsoleReplay() {
return buildConsoleReplay();
},
/**
* Get an Object containing all registered components. Useful for debugging.
* @returns {*}
*/
registeredComponents() {
return ComponentRegistry.components();
},
/**
* Get an Object containing all registered store generators. Useful for debugging.
* @returns {*}
*/
storeGenerators() {
return StoreRegistry.storeGenerators();
},
/**
* Get an Object containing all hydrated stores. Useful for debugging.
* @returns {*}
*/
stores() {
return StoreRegistry.stores();
},
resetOptions() {
this._options = Object.assign({}, DEFAULT_OPTIONS);
},
};
ReactOnRails.resetOptions();
ClientStartup.clientStartup(ctx);
export default ctx.ReactOnRails;