Skip to content

Commit 10c3116

Browse files
author
Michael Trotter
committed
Split the spec component type from ReactComponent; fix toReactComponent
1 parent 5161ed1 commit 10c3116

3 files changed

Lines changed: 49 additions & 26 deletions

File tree

src/React/Basic.js

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ exports.createComponent_ = function(noUpdate, buildStateUpdate, displayName) {
77
function contextToSelf(instance) {
88
var self = {
99
props: instance.props.$$props,
10-
state: instance.state === undefined ? undefined : instance.state.$$state,
10+
state: instance.state === null ? null : instance.state.$$state,
1111
readProps: function() {
1212
return self.instance_.props.$$props;
1313
},
1414
readState: function() {
1515
var state = self.instance_.state;
16-
return state === undefined ? undefined : state.$$state;
16+
return state === null ? null : state.$$state;
1717
},
1818
send: function(action) {
1919
return function() {
@@ -39,7 +39,7 @@ exports.createComponent_ = function(noUpdate, buildStateUpdate, displayName) {
3939
return self;
4040
}
4141

42-
var defaultInitialState = {};
42+
var defaultInitialState = null;
4343
var defaultShouldUpdate = function() {
4444
return function() {
4545
return function() {
@@ -69,10 +69,10 @@ exports.createComponent_ = function(noUpdate, buildStateUpdate, displayName) {
6969
this.$$spec = props.$$spec;
7070
this.state =
7171
// React may optimize components with no state,
72-
// so we leave state undefined if it was left as
72+
// so we leave state null if it was left as
7373
// the default value.
7474
this.$$spec.initialState === defaultInitialState
75-
? undefined
75+
? null
7676
: { $$state: this.$$spec.initialState };
7777
return this;
7878
};
@@ -117,12 +117,12 @@ exports.createStatelessComponent = function(displayName) {
117117
function contextToSelf(instance) {
118118
var self = {
119119
props: instance.props.$$props,
120-
state: undefined,
120+
state: null,
121121
readProps: function() {
122122
return self.instance_.props.$$props;
123123
},
124124
readState: function() {
125-
return undefined;
125+
return null;
126126
},
127127
send: function() {
128128
return function() {};
@@ -132,7 +132,7 @@ exports.createStatelessComponent = function(displayName) {
132132
return self;
133133
}
134134

135-
var defaultInitialState = {};
135+
var defaultInitialState = null;
136136
var defaultShouldUpdate = function() {
137137
return function() {
138138
return function() {
@@ -183,16 +183,36 @@ exports.createStatelessComponent = function(displayName) {
183183
};
184184
};
185185

186-
exports.make = function(component) {
186+
exports.make = function($$spec) {
187187
return function($$props) {
188188
var props = {
189189
$$props: $$props,
190-
$$spec: component
190+
$$spec: $$spec
191191
};
192-
return React.createElement(component.$$type, props);
192+
return React.createElement($$spec.$$type, props);
193193
};
194194
};
195195

196+
exports.toReactComponent = function($$spec) {
197+
var Component = function constructor() {
198+
return this;
199+
};
200+
201+
Component.prototype = Object.create(React.Component.prototype);
202+
203+
Component.displayName = $$spec.$$type.displayName + " (Wrapper)";
204+
205+
Component.prototype.render = function() {
206+
var props = {
207+
$$props: this.props,
208+
$$spec: $$spec
209+
};
210+
return React.createElement($$spec.$$type, props);
211+
};
212+
213+
return Component;
214+
};
215+
196216
exports.keyed_ = function(key, child) {
197217
return React.createElement(Fragment, { key: key }, child);
198218
};
@@ -204,9 +224,7 @@ exports.element_ = function(component, props) {
204224
);
205225
};
206226

207-
exports.elementKeyed_ = function(key, child) {
208-
return React.createElement.call(null, Fragment, { key: key }, child);
209-
};
227+
exports.elementKeyed_ = exports.element_;
210228

211229
exports.fragment = function(children) {
212230
return React.createElement.apply(null, [Fragment, {}].concat(children));

src/React/Basic.purs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ module React.Basic
22
( Component
33
, StatelessComponent
44
, ComponentSpec
5+
, ComponentType
56
, JSX
67
, Update
78
, StateUpdate(..)
@@ -42,8 +43,10 @@ instance semigroupJSX :: Semigroup JSX where
4243
instance monoidJSX :: Monoid JSX where
4344
mempty = empty
4445

46+
data ComponentType props state action
47+
4548
type ComponentSpec props state action =
46-
{ "$$type" :: ReactComponent props
49+
{ "$$type" :: ComponentType props state action
4750
, initialState :: state
4851
, shouldUpdate :: LimitedSelf props state -> props -> state -> Boolean
4952
, didMount :: Self props state action -> Effect Unit
@@ -187,7 +190,7 @@ data ReactComponentInstance
187190

188191
createComponent
189192
:: String
190-
-> { "$$type" :: forall props. ReactComponent props
193+
-> { "$$type" :: forall props state action. ComponentType props state action
191194
, initialState :: forall state. state
192195
, shouldUpdate :: forall props state. LimitedSelf props state -> props -> state -> Boolean
193196
, didMount :: forall props state action. Self props state action -> Effect Unit
@@ -206,7 +209,7 @@ foreign import createComponent_
206209
, effects :: Nullable (Self props state action -> Effect Unit)
207210
})
208211
String
209-
({ "$$type" :: forall props. ReactComponent props
212+
({ "$$type" :: forall props state action. ComponentType props state action
210213
, initialState :: forall state. state
211214
, shouldUpdate :: forall props state. LimitedSelf props state -> props -> state -> Boolean
212215
, didMount :: forall props state action. Self props state action -> Effect Unit
@@ -219,7 +222,7 @@ foreign import createComponent_
219222
-- | Creates a named, stateless component
220223
foreign import createStatelessComponent
221224
:: String
222-
-> { "$$type" :: forall props. ReactComponent props
225+
-> { "$$type" :: forall props state action. ComponentType props state action
223226
, initialState :: Void
224227
, shouldUpdate :: forall props. LimitedSelf props Void -> props -> Void -> Boolean
225228
, didMount :: forall props. Self props Void Void -> Effect Unit
@@ -270,5 +273,7 @@ foreign import element_ :: forall props. Fn2 (ReactComponent { | props }) { | pr
270273

271274
foreign import elementKeyed_ :: forall props. Fn2 (ReactComponent { | props }) { key :: String | props } JSX
272275

273-
toReactComponent :: forall props. ({ | props } -> JSX) -> ReactComponent { | props }
274-
toReactComponent = unsafeCoerce
276+
foreign import toReactComponent :: forall props state action. ComponentSpec { | props } state action -> ReactComponent { | props }
277+
278+
displayName :: forall props state action. ComponentSpec props state action -> String
279+
displayName = _.displayName <<< unsafeCoerce <<< _."$$type"

src/React/Basic/Compat.purs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,18 @@ component
2222
}
2323
-> ReactComponent { | props }
2424
component { displayName, initialState, receiveProps, render } =
25-
toReactComponent (make (createComponent displayName)
25+
toReactComponent (createComponent displayName)
2626
{ initialState = initialState
2727
, didMount = receiveProps <<< selfToLegacySelf
2828
, didUpdate = receiveProps <<< selfToLegacySelf
29-
, update = \self newState -> Update newState
29+
, update = \self stateUpdate -> Update (stateUpdate self.state)
3030
, render = render <<< selfToLegacySelf
31-
})
31+
}
3232
where
3333
selfToLegacySelf { props, state, send } =
3434
{ props
3535
, state
36-
, setState: \fn -> send (fn state)
36+
, setState: send
3737
}
3838

3939
-- | Supports a common subset of the v2 API to ease the upgrade process
@@ -44,6 +44,6 @@ stateless
4444
}
4545
-> ReactComponent { | props }
4646
stateless { displayName, render } =
47-
toReactComponent (make (createStatelessComponent displayName)
47+
toReactComponent (createStatelessComponent displayName)
4848
{ render = \self -> render self.props
49-
})
49+
}

0 commit comments

Comments
 (0)