2
2
3
3
var React = require ( 'react' ) ;
4
4
var invariant = require ( 'react/lib/invariant' ) ;
5
- var Future = require ( 'fibers/future ' ) ;
6
- var Fiber = require ( 'fibers ' ) ;
7
- var getComponentFingerprint = require ( './getComponentFingerprint ' ) ;
5
+ var BaseMixin = require ( './lib/BaseMixin ' ) ;
6
+ var getComponentFingerprint = require ( './lib/getComponentFingerprint ' ) ;
7
+ var injectIntoMarkup = require ( './lib/injectIntoMarkup ' ) ;
8
8
9
- /**
10
- * Create a component class which can get a part of its state by executing async
11
- * routine.
12
- *
13
- * @param {Object } spec
14
- */
15
- function createClass ( spec ) {
16
-
17
- invariant (
18
- spec . render ,
19
- 'ReactAsync.createClass(...): Class specification must implement a `render` method.'
20
- ) ;
21
-
22
- invariant (
23
- spec . getInitialStateAsync ,
24
- 'ReactAsync.createClass(...): Class specification must implement a `getInitialStateAsync` method. ' +
25
- 'Otherwise you should use React.createClass(...) method to create components with no async ' +
26
- 'data fetching'
27
- ) ;
28
-
29
- var render = spec . render ;
30
-
31
- spec . render = function ( ) {
32
- var getInitialStateAsync = Future . wrap ( spec . getInitialStateAsync . bind ( this ) ) ;
33
- var state = getInitialStateAsync ( ) . wait ( ) ;
34
- Fiber . current . __reactAsyncStatePacket [ getComponentFingerprint ( this ) ] = state ;
35
- this . state = this . state || { } ;
36
- for ( var k in state )
37
- this . state [ k ] = state [ k ] ;
38
- return render . call ( this ) ;
39
- }
9
+ var Mixin = {
10
+ mixins : [ BaseMixin ] ,
11
+
12
+ getDefaultProps : function ( ) {
13
+
14
+ var Fiber ;
15
+
16
+ try {
17
+ Fiber = require ( 'fibers' ) ;
18
+ } catch ( err ) {
19
+
20
+ }
21
+
22
+ if ( Fiber === undefined || Fiber . current === undefined ) {
23
+ return { } ;
24
+ }
25
+
26
+ invariant (
27
+ typeof this . getInitialStateAsync === 'function' ,
28
+ this . displayName + ' component must implement a `getInitialStateAsync` method. ' +
29
+ 'Otherwise you should not use ReactAsyncMixin.Mixin'
30
+ ) ;
31
+
32
+ var Future = require ( 'fibers/future' ) ;
40
33
41
- return React . createClass ( spec ) ;
34
+ var getInitialStateAsync = Future . wrap ( this . getInitialStateAsync ) ;
35
+ var asyncState = getInitialStateAsync ( ) . wait ( ) ;
36
+ var fingerprint = getComponentFingerprint ( this ) ;
37
+ Fiber . current . __reactAsyncStatePacket [ fingerprint ] = asyncState ;
38
+ return { asyncState : asyncState } ;
39
+ }
42
40
}
43
41
44
42
/**
45
- * Render component markup asynchronously.
43
+ * Prefetch async state recursively and render component markup asynchronously.
46
44
*
47
45
* @param {ReactComponent } component
48
46
* @param {Function<Error, String, Object> } cb
49
47
*/
50
- function renderComponentToString ( component , cb ) {
48
+ function renderComponentToStringWithAsyncState ( component , cb ) {
49
+
50
+ try {
51
+ var Fiber = require ( 'fibers' ) ;
52
+ } catch ( err ) {
53
+ console . error ( 'install fibers: npm install fibers' ) ;
54
+ throw err ;
55
+ }
56
+
51
57
Fiber ( function ( ) { // jshint ignore:line
52
58
try {
53
59
Fiber . current . __reactAsyncStatePacket = { } ;
@@ -69,31 +75,10 @@ function renderComponentToString(component, cb) {
69
75
} ) . run ( ) ;
70
76
}
71
77
72
- /**
73
- * Inject data and optional client scripts into markup.
74
- *
75
- * @param {String } markup
76
- * @param {Object } data
77
- * @param {?Array } scripts
78
- */
79
- function injectIntoMarkup ( markup , data , scripts ) {
80
- var injected = '<script>window.__reactAsyncStatePacket=' + JSON . stringify ( data ) + '</script>' ;
81
-
82
- if ( scripts ) {
83
- injected += scripts . map ( function ( script ) {
84
- return '<script src="' + script + '"></script>' ;
85
- } ) . join ( '' ) ;
86
- }
87
-
88
- if ( markup . indexOf ( '</body>' ) > - 1 ) {
89
- return markup . replace ( '</body>' , injected + '$&' ) ;
90
- } else {
91
- return markup + injected ;
92
- }
93
- }
94
-
95
78
module . exports = {
96
- renderComponentToString : renderComponentToString ,
97
- injectIntoMarkup : injectIntoMarkup ,
98
- createClass : createClass
79
+ prefetchAsyncState : require ( './lib/prefetchAsyncState' ) ,
80
+ isAsyncComponent : require ( './lib/isAsyncComponent' ) ,
81
+ Mixin : Mixin ,
82
+ renderComponentToStringWithAsyncState : renderComponentToStringWithAsyncState ,
83
+ injectIntoMarkup : injectIntoMarkup
99
84
} ;
0 commit comments