33#### ` ComponentSpec `
44
55``` purescript
6- type ComponentSpec props state initialState action = { initialState :: initialState , update :: Self props state action -> action -> StateUpdate props state action, render :: Self props state action -> JSX, shouldUpdate :: Self props state action -> props -> state -> Boolean, didMount :: Self props state action -> Effect Unit, didUpdate :: Self props state action -> Effect Unit, willUnmount :: Self props state action -> Effect Unit, "$$type" :: ComponentType props state action }
6+ type ComponentSpec props state action = ( initialState :: state , update :: Self props state action -> action -> StateUpdate props state action, render :: Self props state action -> JSX, shouldUpdate :: Self props state action -> props -> state -> Boolean, didMount :: Self props state action -> Effect Unit, didUpdate :: Self props state action -> Effect Unit, willUnmount :: Self props state action -> Effect Unit)
77```
88
99` ComponentSpec ` represents a React-Basic component implementation.
@@ -13,7 +13,7 @@ with specific implementations. None are required to be overridden, unless
1313an overridden function interacts with ` state ` , in which case ` initialState `
1414is required (the compiler enforces this). While you _ can_ use ` state ` and
1515dispatch actions without defining ` update ` , doing so doesn't make much sense
16- so the default ` update ` implementation will emit a warning.
16+ and will emit a warning.
1717
1818- ` initialState `
1919 - The component's starting state.
@@ -26,7 +26,7 @@ so the default `update` implementation will emit a warning.
2626- ` render `
2727 - Takes a current snapshot of the component (` Self ` ) and converts it to renderable ` JSX ` .
2828- ` shouldUpdate `
29- - Can be useful for occasional performance optimizations. Rarely necessary.
29+ - Can be useful for performance optimizations. Rarely necessary.
3030- ` didMount `
3131 - The React component's ` componentDidMount ` lifecycle. Useful for initiating an action on first mount, such as fetching data from a server.
3232- ` didUpdate `
@@ -35,14 +35,13 @@ so the default `update` implementation will emit a warning.
3535 - The React component's ` componentWillUpdate ` lifecycle. Any subscriptions or timers created in ` didMount ` or ` didUpdate ` should be disposed of here.
3636
3737The component spec is generally not exported from your component
38- module and this type is rarely used explicitly. The simplified alias
39- ` Component ` is usually sufficient, and ` make ` will validate whether
40- your component's types line up.
38+ module and this type is rarely used explicitly. ` make ` will validate whether
39+ your component's internal types line up.
4140
4241For example:
4342
4443``` purs
45- component :: Component
44+ component :: Component Props
4645component = createComponent "Counter"
4746
4847type Props =
@@ -53,14 +52,14 @@ data Action
5352 = Increment
5453
5554counter :: Props -> JSX
56- counter = make component
55+ counter: make component
5756 { initialState = { counter: 0 }
5857
59- , update = \self action -> case action of
58+ , update: \self action -> case action of
6059 Increment ->
6160 Update self.state { counter = self.state.counter + 1 }
6261
63- , render = \self ->
62+ , render: \self ->
6463 R.button
6564 { onClick: capture_ self Increment
6665 , children: [ R.text (self.props.label <> ": " <> show self.state.counter) ]
@@ -73,53 +72,54 @@ This example component overrides `initialState`, `update`, and `render`.
7372__ * Note:* A ` ComponentSpec ` is * not* a valid React component by itself. If you would like to use
7473 a React-Basic component from JavaScript, use ` toReactComponent ` .__
7574
76- __ * Note:* ` $$type ` is for internal use only. It needs to be on the type to
77- preserve its existence during a record update, as in the example above.__
78-
7975__ * See also:* ` Component ` , ` ComponentSpec ` , ` make ` , ` makeStateless ` __
8076
8177#### ` createComponent `
8278
8379``` purescript
84- createComponent :: forall props state action . String -> ComponentSpec props state Unit action
80+ createComponent :: forall props. String -> Component props
8581```
8682
87- Creates a ` ComponentSpec ` with a given Display Name.
83+ Creates a ` Component ` with a given Display Name.
8884
8985The resulting component spec is usually given the simplified ` Component ` type:
9086
9187``` purs
92- component :: Component
88+ component :: Component Props
9389component = createComponent "Counter"
9490```
9591
9692This function should be used at the module level and considered side effecting.
9793This is because React uses referential equality when deciding whether a new
98- ` JSX ` tree is a valid update, or if it needs to be replaced entirely
94+ ` JSX ` tree is a valid update or if it needs to be replaced entirely
9995(expensive and clears component state lower in the tree).
10096
97+ __ * Note:* A specific type for the props in ` Component props ` should always be chosen at this point.
98+ It's technically possible to declare the component with ` forall props. Component props `
99+ but doing so is unsafe. Leaving the prop type open allows the use of a single ` Component `
100+ definition in multiple React-Basic components that may have different prop types. Because
101+ component lifecycles are managed by React, it becomes possible for incompatible prop values to
102+ be passed by React into lifecycle functions.__
103+
101104__ * Note:* A ` Component ` is * not* a valid React component by itself. If you would like to use
102105 a React-Basic component from JavaScript, use ` toReactComponent ` .__
103106
104- __ * See also:* ` Component ` , ` ComponentSpec ` , ` make ` , ` makeStateless ` __
107+ __ * See also:* ` Component ` , ` make ` , ` makeStateless ` __
105108
106109#### ` Component `
107110
108111``` purescript
109- type Component = forall props state action. ComponentSpec props state Unit action
112+ data Component props
110113```
111114
112115A simplified alias for ` ComponentSpec ` . This type is usually used to represent
113116the default component type returned from ` createComponent ` .
114-
115- #### ` ComponentType `
116-
117- ``` purescript
118- data ComponentType props state action
119- ```
120-
121117Opaque component information for internal use.
122118
119+ __ * Note:* Never define a component with
120+ a less specific type for ` props ` than its associated ` ComponentSpec ` and ` make `
121+ calls, as this can lead to unsafe interactions with React's lifecycle management.__
122+
123123__ * For the curious:* This is the "class" React will use to render and
124124 identify the component. It receives the ` ComponentSpec ` as a prop and knows
125125 how to defer behavior to it. It requires very specific props and is not useful by
@@ -138,7 +138,7 @@ data StateUpdate props state action
138138Used by the ` update ` function to describe the kind of state update and/or side
139139effects desired.
140140
141- __ * See also:* ` ComponentSpec ` __
141+ __ * See also:* ` ComponentSpec ` , ` capture ` __
142142
143143#### ` Self `
144144
@@ -255,14 +255,14 @@ __*See also:* `Self`__
255255#### ` make `
256256
257257``` purescript
258- make :: forall props state action. ComponentSpec props state state action -> props -> JSX
258+ make :: forall spec spec_ props state action. Union spec spec_ ( ComponentSpec props state action) => Component props -> { render :: Self props state action -> JSX | spec } -> props -> JSX
259259```
260260
261- Turn a ` Component ` into a usable render function.
261+ Turn a ` Component ` and ` ComponentSpec ` into a usable render function.
262262This is where you will want to provide customized implementations:
263263
264264``` purs
265- component :: Component
265+ component :: Component Props
266266component = createComponent "Counter"
267267
268268type Props =
@@ -274,13 +274,13 @@ data Action
274274
275275counter :: Props -> JSX
276276counter = make component
277- { initialState = { counter: 0 }
277+ { initialState: { counter: 0 }
278278
279- , update = \self action -> case action of
279+ , update: \self action -> case action of
280280 Increment ->
281281 Update self.state { counter = self.state.counter + 1 }
282282
283- , render = \self ->
283+ , render: \self ->
284284 R.button
285285 { onClick: capture_ self Increment
286286 , children: [ R.text (self.props.label <> ": " <> show self.state.counter) ]
@@ -293,13 +293,13 @@ __*See also:* `makeStateless`, `createComponent`, `Component`, `ComponentSpec`__
293293#### ` makeStateless `
294294
295295``` purescript
296- makeStateless :: forall props. ComponentSpec props Unit Unit Unit -> (props -> JSX) -> props -> JSX
296+ makeStateless :: forall props. Component props -> (props -> JSX) -> props -> JSX
297297```
298298
299299Makes stateless component definition slightly less verbose:
300300
301301``` purs
302- component :: Component
302+ component :: Component Props
303303component = createComponent "Xyz"
304304
305305myComponent :: Props -> JSX
@@ -398,6 +398,28 @@ imported from FFI.
398398
399399__ * See also:* ` ReactComponent ` , ` element ` , React's documentation regarding the special ` key ` prop__
400400
401+ #### ` displayNameFromComponent `
402+
403+ ``` purescript
404+ displayNameFromComponent :: forall props. Component props -> String
405+ ```
406+
407+ Retrieve the Display Name from a ` ComponentSpec ` . Useful for debugging and improving
408+ error messages in logs.
409+
410+ __ * See also:* ` displayNameFromSelf ` , ` createComponent ` __
411+
412+ #### ` displayNameFromSelf `
413+
414+ ``` purescript
415+ displayNameFromSelf :: forall props state action. Self props state action -> String
416+ ```
417+
418+ Retrieve the Display Name from a ` Self ` . Useful for debugging and improving
419+ error messages in logs.
420+
421+ __ * See also:* ` displayNameFromComponent ` , ` createComponent ` __
422+
401423#### ` ReactComponent `
402424
403425``` purescript
@@ -426,7 +448,7 @@ caution.
426448#### ` toReactComponent `
427449
428450``` purescript
429- toReactComponent :: forall jsProps props state action. ( { | jsProps } -> props) -> ComponentSpec props state state action -> ReactComponent { | jsProps }
451+ toReactComponent :: forall spec spec_ jsProps props state action. Union spec spec_ (ComponentSpec props state action) => ( { | jsProps } -> props) -> Component props -> { render :: Self props state action -> JSX | spec } -> ReactComponent { | jsProps }
430452```
431453
432454Convert a React-Basic ` ComponentSpec ` to a JavaScript-friendly React component.
0 commit comments