Skip to content

Commit 9d4eda2

Browse files
committed
Merge pull request #9 from spicydonuts/hook-creation
Hook creation and aliasing/newtyping
2 parents eb95b6d + 2939018 commit 9d4eda2

File tree

14 files changed

+380
-262
lines changed

14 files changed

+380
-262
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ If we prefer this API over the existing react-basic API, we may eventually repla
1515
## Example
1616

1717
```purs
18-
mkCounter :: CreateComponent {}
18+
mkCounter :: Effect (ReactComponent {})
1919
mkCounter = do
2020
component "Counter" \props -> React.do
2121
counter /\ setCounter <- useState 0

examples/aff/src/AffEx.purs

+4-3
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@ module AffEx where
33
import Prelude
44
import Data.Either (either)
55
import Data.Maybe (Maybe(..), maybe)
6+
import Effect (Effect)
67
import Effect.Aff (Aff, Milliseconds(..), delay, error, message, throwError)
78
import React.Basic.DOM as R
89
import React.Basic.Events (handler_)
9-
import React.Basic.Hooks (type (/\), CreateComponent, Hook, JSX, component, element, fragment, useState, (/\))
10+
import React.Basic.Hooks (type (/\), ReactComponent, Hook, JSX, component, element, fragment, useState, (/\))
1011
import React.Basic.Hooks as React
1112
import React.Basic.Hooks.Aff (useAff)
1213

13-
mkAffEx :: CreateComponent {}
14+
mkAffEx :: Effect (ReactComponent {})
1415
mkAffEx = do
1516
-- A component for fetching and rendering a Cat entity.
1617
catDetails <- mkCatDetails
@@ -68,7 +69,7 @@ mkAffEx = do
6869
-- Hooks can't be used conditionally but components can!
6970
-- Not needing to deal with a `Maybe` key simplifies this
7071
-- compoennt a bit.
71-
mkCatDetails :: CreateComponent { catKey :: Key Cat }
72+
mkCatDetails :: Effect (ReactComponent { catKey :: Key Cat })
7273
mkCatDetails = do
7374
component "CatDetails" \{ catKey } -> React.do
7475
cat <- useAff catKey $ fetch catKey

examples/component/src/Container.purs

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
module Container where
22

33
import Prelude
4-
5-
import React.Basic.Hooks(CreateComponent, component, element)
4+
import Effect (Effect)
65
import React.Basic.DOM as R
6+
import React.Basic.Hooks (ReactComponent, component, element)
77
import ToggleButton (mkToggleButton)
88

9-
mkToggleButtonContainer :: CreateComponent {}
9+
mkToggleButtonContainer :: Effect (ReactComponent {})
1010
mkToggleButtonContainer = do
1111
toggleButton <- mkToggleButton
12-
1312
component "Container" \_ ->
14-
pure $ R.div
15-
{ children:
16-
[ element toggleButton { label: "A" }
17-
, element toggleButton { label: "B" }
18-
]
19-
}
13+
pure
14+
$ R.div
15+
{ children:
16+
[ element toggleButton { label: "A" }
17+
, element toggleButton { label: "B" }
18+
]
19+
}
+11-12
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,25 @@
11
module ToggleButton where
22

33
import Prelude
4-
4+
import Effect (Effect)
55
import Effect.Console (log)
66
import React.Basic.DOM as R
77
import React.Basic.Events (handler_)
8-
import React.Basic.Hooks (CreateComponent, component, useEffect, useState, (/\))
8+
import React.Basic.Hooks (ReactComponent, component, useEffect, useState, (/\))
99
import React.Basic.Hooks as React
1010

11-
mkToggleButton :: CreateComponent { label :: String }
11+
mkToggleButton :: Effect (ReactComponent { label :: String })
1212
mkToggleButton = do
1313
component "ToggleButton" \{ label } -> React.do
1414
on /\ setOn <- useState false
15-
1615
useEffect on do
1716
log $ "State: " <> if on then "On" else "Off"
1817
pure (pure unit)
19-
20-
pure $ R.button
21-
{ onClick: handler_ $ setOn not
22-
, children:
23-
[ R.text label
24-
, R.text if on then " On" else " Off"
25-
]
26-
}
18+
pure
19+
$ R.button
20+
{ onClick: handler_ $ setOn not
21+
, children:
22+
[ R.text label
23+
, R.text if on then " On" else " Off"
24+
]
25+
}

examples/context/src/Context.purs

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ import Prelude
44
import Effect (Effect)
55
import React.Basic.DOM as R
66
import React.Basic.Events (handler_)
7-
import React.Basic.Hooks (type (/\), CreateComponent, JSX, ReactContext, component, createContext, element, provider, useContext, useState, (/\))
7+
import React.Basic.Hooks (type (/\), ReactComponent, JSX, ReactContext, component, createContext, element, provider, useContext, useState, (/\))
88
import React.Basic.Hooks as React
99

10-
mkContext :: CreateComponent {}
10+
mkContext :: Effect (ReactComponent {})
1111
mkContext = do
1212
counterContext <- createContext (0 /\ pure unit)
1313
store <- mkStore counterContext
@@ -24,7 +24,7 @@ mkContext = do
2424

2525
mkStore ::
2626
ReactContext (Int /\ (Effect Unit)) ->
27-
CreateComponent { children :: Array JSX }
27+
Effect (ReactComponent { children :: Array JSX })
2828
mkStore context = do
2929
component "Store" \{ children } -> React.do
3030
counter /\ setCounter <- useState 0
@@ -37,7 +37,7 @@ mkStore context = do
3737

3838
mkCounter ::
3939
ReactContext (Int /\ (Effect Unit)) ->
40-
CreateComponent {}
40+
Effect (ReactComponent {})
4141
mkCounter counterContext = do
4242
component "Counter" \props -> React.do
4343
counter /\ increment <- useContext counterContext
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,50 @@
11
module ControlledInput where
22

33
import Prelude
4-
54
import Data.Maybe (Maybe(..), fromMaybe, maybe)
5+
import Effect (Effect)
66
import React.Basic.DOM as R
77
import React.Basic.DOM.Events (preventDefault, stopPropagation, targetValue, timeStamp)
88
import React.Basic.Events (EventHandler, handler, merge)
9-
import React.Basic.Hooks (CreateComponent, UseState, Hook, component, fragment, useState, (/\))
9+
import React.Basic.Hooks (ReactComponent, UseState, Hook, component, fragment, useState, (/\))
1010
import React.Basic.Hooks as React
1111

12-
mkControlledInput :: CreateComponent {}
12+
mkControlledInput :: Effect (ReactComponent {})
1313
mkControlledInput = do
1414
component "ControlledInput" \props -> React.do
1515
firstName <- useInput "hello"
1616
lastName <- useInput "world"
17-
18-
pure $ R.form_
19-
[ renderInput firstName
20-
, renderInput lastName
21-
]
17+
pure
18+
$ R.form_
19+
[ renderInput firstName
20+
, renderInput lastName
21+
]
2222
where
23-
renderInput input =
24-
fragment
25-
[ R.input { onChange: input.onChange, value: input.value }
26-
, R.p_ [ R.text ("Current value = " <> show input.value) ]
27-
, R.p_ [ R.text ("Changed at = " <> maybe "never" show input.lastChanged) ]
28-
]
23+
renderInput input =
24+
fragment
25+
[ R.input { onChange: input.onChange, value: input.value }
26+
, R.p_ [ R.text ("Current value = " <> show input.value) ]
27+
, R.p_ [ R.text ("Changed at = " <> maybe "never" show input.lastChanged) ]
28+
]
2929

30-
useInput
31-
:: String
32-
-> Hook
33-
(UseState { value :: String, lastChanged :: Maybe Number })
34-
{ onChange :: EventHandler
35-
, value :: String
36-
, lastChanged :: Maybe Number
37-
}
30+
useInput ::
31+
String ->
32+
Hook
33+
(UseState { value :: String, lastChanged :: Maybe Number })
34+
{ onChange :: EventHandler
35+
, value :: String
36+
, lastChanged :: Maybe Number
37+
}
3838
useInput initialValue = React.do
3939
{ value, lastChanged } /\ replaceState <- useState { value: initialValue, lastChanged: Nothing }
4040
pure
41-
{ onChange: handler
42-
(preventDefault >>> stopPropagation >>> merge { targetValue, timeStamp })
43-
\{ timeStamp, targetValue } -> do
44-
replaceState \_ ->
45-
{ value: fromMaybe "" targetValue
46-
, lastChanged: Just timeStamp
47-
}
41+
{ onChange:
42+
handler
43+
(preventDefault >>> stopPropagation >>> merge { targetValue, timeStamp }) \{ timeStamp, targetValue } -> do
44+
replaceState \_ ->
45+
{ value: fromMaybe "" targetValue
46+
, lastChanged: Just timeStamp
47+
}
4848
, value
4949
, lastChanged
5050
}

examples/counter/src/Counter.purs

+9-11
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,25 @@
11
module Counter where
22

33
import Prelude
4-
54
import Effect (Effect)
65
import React.Basic.DOM as R
76
import React.Basic.Events (handler_)
8-
import React.Basic.Hooks (CreateComponent, component, fragment, useEffect, useState, (/\))
7+
import React.Basic.Hooks (ReactComponent, component, fragment, useEffect, useState, (/\))
98
import React.Basic.Hooks as React
109

11-
mkCounter :: CreateComponent {}
10+
mkCounter :: Effect (ReactComponent {})
1211
mkCounter = do
1312
component "Counter" \props -> React.do
1413
counter /\ setCounter <- useState 0
15-
1614
useEffect counter do
1715
setDocumentTitle $ "Count: " <> show counter
1816
pure mempty
19-
20-
pure $ fragment
21-
[ R.button
22-
{ onClick: handler_ $ setCounter (_ + 1)
23-
, children: [ R.text $ "Increment: " <> show counter ]
24-
}
25-
]
17+
pure
18+
$ fragment
19+
[ R.button
20+
{ onClick: handler_ $ setCounter (_ + 1)
21+
, children: [ R.text $ "Increment: " <> show counter ]
22+
}
23+
]
2624

2725
foreign import setDocumentTitle :: String -> Effect Unit
+13-13
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,27 @@
11
module MemoCallback where
22

33
import Prelude
4-
4+
import Effect (Effect)
55
import Effect.Console (log)
66
import React.Basic.DOM as R
77
import React.Basic.Events (handler_)
8-
import React.Basic.Hooks (CreateComponent, UnsafeReference(..), component, fragment, useCallback, useEffect, useState, (/\))
8+
import React.Basic.Hooks (ReactComponent, UnsafeReference(..), component, fragment, useCallback, useEffect, useState, (/\))
99
import React.Basic.Hooks as React
1010

11-
mkMemoCallback :: CreateComponent {}
11+
mkMemoCallback :: Effect (ReactComponent {})
1212
mkMemoCallback = do
1313
component "MemoCallback" \props -> React.do
1414
counter /\ setCounter <- useState 0
15-
increment <- useCallback (UnsafeReference setCounter) $
16-
setCounter (_ + 1)
17-
15+
increment <-
16+
useCallback (UnsafeReference setCounter)
17+
$ setCounter (_ + 1)
1818
useEffect (UnsafeReference increment) do
1919
log "increment updated"
2020
pure mempty
21-
22-
pure $ fragment
23-
[ R.button
24-
{ onClick: handler_ increment
25-
, children: [ R.text $ "Increment: " <> show counter ]
26-
}
27-
]
21+
pure
22+
$ fragment
23+
[ R.button
24+
{ onClick: handler_ increment
25+
, children: [ R.text $ "Increment: " <> show counter ]
26+
}
27+
]

examples/reducer/src/Reducer.purs

+16-17
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,34 @@
11
module Reducer where
22

33
import Prelude
4-
4+
import Effect (Effect)
55
import React.Basic.DOM as R
66
import React.Basic.Events (handler_)
7-
import React.Basic.Hooks (CreateComponent, component, fragment, useReducer, (/\))
7+
import React.Basic.Hooks (ReactComponent, component, fragment, useReducer, (/\))
88
import React.Basic.Hooks as React
99

1010
data Action
1111
= Increment
1212
| Decrement
1313

14-
mkReducer :: CreateComponent {}
14+
mkReducer :: Effect (ReactComponent {})
1515
mkReducer = do
1616
component "Reducer" \props -> React.do
17-
1817
state /\ dispatch <-
1918
useReducer { counter: 0 } \state -> case _ of
2019
Increment -> state { counter = state.counter + 1 }
2120
Decrement -> state { counter = state.counter - 1 }
22-
23-
pure $ fragment
24-
[ R.button
25-
{ onClick: handler_ $ dispatch Decrement
26-
, children: [ R.text $ "Decrement" ]
27-
}
28-
, R.button
29-
{ onClick: handler_ $ dispatch Increment
30-
, children: [ R.text $ "Increment" ]
31-
}
32-
, R.div_
33-
[ R.text $ show state.counter
21+
pure
22+
$ fragment
23+
[ R.button
24+
{ onClick: handler_ $ dispatch Decrement
25+
, children: [ R.text $ "Decrement" ]
26+
}
27+
, R.button
28+
{ onClick: handler_ $ dispatch Increment
29+
, children: [ R.text $ "Increment" ]
30+
}
31+
, R.div_
32+
[ R.text $ show state.counter
33+
]
3434
]
35-
]

0 commit comments

Comments
 (0)