1
1
-- | This module defines foreign types and functions which wrap React's functionality.
2
2
3
3
module React
4
- ( ReactElement
4
+ ( class ReactRender
5
+ , ReactElement
5
6
, ReactComponent
6
7
, ReactThis
7
8
, TagName
@@ -25,6 +26,7 @@ module React
25
26
, GetInitialState
26
27
, ComponentWillMount
27
28
, ComponentDidMount
29
+ , ComponentDidCatch
28
30
, ComponentWillReceiveProps
29
31
, ShouldComponentUpdate
30
32
, ComponentWillUpdate
@@ -76,8 +78,10 @@ module React
76
78
import Prelude
77
79
78
80
import Control.Monad.Eff (kind Effect , Eff )
79
- import Data.Maybe (Maybe )
80
- import Data.Nullable (Nullable , toMaybe )
81
+ import Control.Monad.Eff.Exception (Error )
82
+ import Data.Function.Uncurried (Fn2 , runFn2 )
83
+ import Data.Maybe (Maybe (Nothing))
84
+ import Data.Nullable (Nullable , toMaybe , toNullable )
81
85
import Control.Monad.Eff.Uncurried (EffFn2 , runEffFn2 )
82
86
import Unsafe.Coerce (unsafeCoerce )
83
87
@@ -160,15 +164,27 @@ type EventHandlerContext eff props state result =
160
164
| eff
161
165
) result
162
166
167
+ class ReactRender a
168
+
169
+ instance arrayReactRender :: ReactRender (Array ReactElement )
170
+
171
+ instance reactElementReactRender :: ReactRender ReactElement
172
+
173
+ instance stringReactRender :: ReactRender String
174
+
175
+ instance intReactRender :: ReactRender Int
176
+
177
+ instance numberReactRender :: ReactRender Number
178
+
163
179
-- | A render function.
164
- type Render props state eff =
180
+ type Render props state render eff =
165
181
ReactThis props state ->
166
182
Eff
167
183
( props :: ReactProps
168
184
, refs :: ReactRefs Disallowed
169
185
, state :: ReactState ReadOnly
170
186
| eff
171
- ) ReactElement
187
+ ) render
172
188
173
189
-- | A get initial state function.
174
190
type GetInitialState props state eff =
@@ -200,6 +216,18 @@ type ComponentDidMount props state eff =
200
216
| eff
201
217
) Unit
202
218
219
+ type ComponentDidCatch props state eff =
220
+ ReactThis props state ->
221
+ Error ->
222
+ { componentStack :: String } ->
223
+ Eff
224
+ ( props :: ReactProps
225
+ , state :: ReactState ReadWrite
226
+ , refs :: ReactRefs ReadOnly
227
+ | eff
228
+ ) Unit
229
+
230
+
203
231
-- | A component will receive props function.
204
232
type ComponentWillReceiveProps props state eff =
205
233
ReactThis props state ->
@@ -258,12 +286,13 @@ type ComponentWillUnmount props state eff =
258
286
) Unit
259
287
260
288
-- | A specification of a component.
261
- type ReactSpec props state eff =
262
- { render :: Render props state eff
289
+ type ReactSpec props state render eff =
290
+ { render :: Render props state render eff
263
291
, displayName :: String
264
292
, getInitialState :: GetInitialState props state eff
265
293
, componentWillMount :: ComponentWillMount props state eff
266
294
, componentDidMount :: ComponentDidMount props state eff
295
+ , componentDidCatch :: Maybe (ComponentDidCatch props state eff )
267
296
, componentWillReceiveProps :: ComponentWillReceiveProps props state eff
268
297
, shouldComponentUpdate :: ShouldComponentUpdate props state eff
269
298
, componentWillUpdate :: ComponentWillUpdate props state eff
@@ -272,21 +301,24 @@ type ReactSpec props state eff =
272
301
}
273
302
274
303
-- | Create a component specification with a provided state.
275
- spec :: forall props state eff .
276
- state -> Render props state eff -> ReactSpec props state eff
304
+ spec :: forall props state render eff .
305
+ ReactRender render =>
306
+ state -> Render props state render eff -> ReactSpec props state render eff
277
307
spec state = spec' \_ -> pure state
278
308
279
309
-- | Create a component specification with a get initial state function.
280
- spec' :: forall props state eff .
310
+ spec' :: forall props state render eff .
311
+ ReactRender render =>
281
312
GetInitialState props state eff ->
282
- Render props state eff ->
283
- ReactSpec props state eff
313
+ Render props state render eff ->
314
+ ReactSpec props state render eff
284
315
spec' getInitialState renderFn =
285
316
{ render: renderFn
286
317
, displayName: " "
287
318
, getInitialState: getInitialState
288
319
, componentWillMount: \_ -> pure unit
289
320
, componentDidMount: \_ -> pure unit
321
+ , componentDidCatch: Nothing
290
322
, componentWillReceiveProps: \_ _ -> pure unit
291
323
, shouldComponentUpdate: \_ _ _ -> pure true
292
324
, componentWillUpdate: \_ _ _ -> pure unit
@@ -357,17 +389,32 @@ foreign import transformState :: forall props state eff.
357
389
Eff (state :: ReactState ReadWrite | eff ) Unit
358
390
359
391
-- | Create a React class from a specification.
360
- foreign import createClass :: forall props state eff .
361
- ReactSpec props state eff -> ReactClass props
362
-
363
- -- | Create a stateless React class.
364
- createClassStateless :: forall props .
365
- (props -> ReactElement ) -> ReactClass props
366
- createClassStateless = unsafeCoerce
392
+ foreign import createClass' :: forall props state render eff .
393
+ Fn2
394
+ (forall a . Maybe a -> Nullable a )
395
+ (ReactSpec props state render eff )
396
+ (ReactClass props )
397
+
398
+ createClass :: forall props state render eff .
399
+ ReactSpec props state render eff -> ReactClass props
400
+ createClass spc = runFn2 createClass' toNullable spc
401
+
402
+ -- | Create a stateless React class. When using a non anonymous function the
403
+ -- | displayName will be the capitalized name of the function, e.g.
404
+ -- | ``` purescript
405
+ -- | helloWorld = createClassStatelesss hellowWorldCls
406
+ -- | where
407
+ -- | hellowWorldCls props = ...
408
+ -- | ```
409
+ -- | Then the `displayName` will be set up to `HellowWorldCls`
410
+ foreign import createClassStateless :: forall props render .
411
+ ReactRender render =>
412
+ (props -> render ) -> ReactClass props
367
413
368
414
-- | Create a stateless React class with children access.
369
- createClassStateless' :: forall props .
370
- (props -> Array ReactElement -> ReactElement ) -> ReactClass props
415
+ createClassStateless' :: forall props render .
416
+ ReactRender render =>
417
+ (props -> Array ReactElement -> render ) -> ReactClass props
371
418
createClassStateless' k =
372
419
createClassStateless \props ->
373
420
k props (childrenToArray (unsafeCoerce props).children)
0 commit comments