Skip to content

Commit 2b3fcde

Browse files
Merge pull request #342 from Larocceau/third-party-react-favor-feliz
third party react library: Move Feliz recipe up
2 parents e9a83e5 + 4184f31 commit 2b3fcde

File tree

1 file changed

+61
-53
lines changed

1 file changed

+61
-53
lines changed
Lines changed: 61 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,9 @@
1-
To use a third-party React library in a SAFE application, you need to write an F# wrapper around it. There are two ways for doing this - using [Fable.React](https://www.nuget.org/packages/Fable.React/) or using [Feliz](https://zaid-ajaj.github.io/Feliz/).
1+
To use a third-party React library in a SAFE application, you need to write an F# wrapper around it. There are two ways for doing this - using [Feliz](https://zaid-ajaj.github.io/Feliz/) or using [Fable.React](https://www.nuget.org/packages/Fable.React/).
2+
23
## Prerequisites
34

45
This recipe uses the [react-d3-speedometer NPM package](https://www.npmjs.com/package/react-d3-speedometer) for demonstration purposes. [Add it to your Client](../package-management/add-npm-package-to-client.md) before continuing.
56

6-
## Fable.React - Setup
7-
8-
#### 1. Create a new file
9-
10-
Create an empty file named `ReactSpeedometer.fs` in the Client project above `Index.fs` and insert the following statements at the beginning of the file.
11-
12-
```fsharp
13-
module ReactSpeedometer
14-
15-
open Fable.Core
16-
open Fable.Core.JsInterop
17-
open Fable.React
18-
```
19-
20-
#### 2. Define the Props
21-
Prop represents the props of the React component. In this recipe, we're using [the props listed here](https://www.npmjs.com/package/react-d3-speedometer) for `react-d3-speedometer`. We model them in Fable.React using a discriminated union.
22-
23-
```fsharp
24-
type Prop =
25-
| Value of int
26-
| MinValue of int
27-
| MaxValue of int
28-
| StartColor of string
29-
```
30-
31-
> One difference to note is that we use **P**ascalCase rather than **c**amelCase.
32-
>
33-
> Note that we can model any props here, both simple values and "event handler"-style ones.
34-
35-
#### 3. Write the Component
36-
Add the following function to the file. Note that the last argument passed into the `ofImport` function is a list of `ReactElements` to be used as children of the react component. In this case, we are passing an empty list since the component doesn't have children.
37-
38-
```fsharp
39-
let reactSpeedometer (props : Prop list) : ReactElement =
40-
let propsObject = keyValueList CaseRules.LowerFirst props // converts Props to JS object
41-
ofImport "default" "react-d3-speedometer" propsObject [] // import the default function/object from react-d3-speedometer
42-
```
43-
44-
#### 4. Use the Component
45-
With all these in place, you can use the React element in your client like so:
46-
47-
```fsharp
48-
open ReactSpeedometer
49-
50-
reactSpeedometer [
51-
Prop.Value 10 // Since Value is already decalred in HTMLAttr you can use Prop.Value to tell the F# compiler its of type Prop and not HTMLAttr
52-
MaxValue 100
53-
MinValue 0
54-
StartColor "red"
55-
]
56-
```
57-
587
## Feliz - Setup
598

609
If you don't already have [Feliz](https://www.nuget.org/packages/Feliz/) installed, [add it to your client](../ui/add-feliz.md).
@@ -65,6 +14,7 @@ open Fable.Core.JsInterop
6514
```
6615

6716
Within the view function
17+
6818
```fsharp
6919
Feliz.Interop.reactApi.createElement (importDefault "react-d3-speedometer", createObj [
7020
"minValue" ==> 0
@@ -75,15 +25,19 @@ Feliz.Interop.reactApi.createElement (importDefault "react-d3-speedometer", crea
7525

7626
- `createElement` from `Feliz.ReactApi.IReactApi` takes the component you're wrapping react-d3-speedometer, the props that component takes and creates a ReactComponent we can use in F#.
7727
- `importDefault` from ` Fable.Core.JsInterop` is giving us access to the component and is equivalent to
28+
7829
```javascript
7930
import ReactSpeedometer from "react-d3-speedometer"
8031
```
32+
8133
The reason for using `importDefault` is the documentation for the component uses a default export "ReactSpeedometer". Please find a list of common import statetments at the end of this recipe
8234

8335
As a quick check to ensure that the library is being imported and we have no typos you can `console.log` the following at the top within the view function
36+
8437
```fsharp
8538
Browser.Dom.console.log("REACT-D3-IMPORT", importDefault "react-d3-speedometer")
8639
```
40+
8741
In the console window (which can be reached by right-clicking and selecting Insepct Element) you should see some output from the above log.
8842
If nothing is being seen you may need a slightly different import statement, [please refer to this recipe](../../v4-recipes/javascript/import-js-module.md).
8943

@@ -96,7 +50,9 @@ createObj [
9650
"maxValue" ==> 10
9751
]
9852
```
53+
9954
Is equivalent to
55+
10056
```javascript
10157
{ minValue: 0, maxValue: 10 }
10258
```
@@ -108,5 +64,57 @@ That's the bare minimum needed to get going!
10864
Once your component is working you may want to extract out the logic so that it can be used in multiple pages of your app.
10965
For a full detailed tutorial head over to [this blog post](https://www.compositional-it.com/news-blog/f-wrappers-for-react-components/)!
11066

67+
## Fable.React - Setup
68+
69+
### 1. Create a new file
70+
71+
Create an empty file named `ReactSpeedometer.fs` in the Client project above `Index.fs` and insert the following statements at the beginning of the file.
72+
73+
```fsharp
74+
module ReactSpeedometer
75+
76+
open Fable.Core
77+
open Fable.Core.JsInterop
78+
open Fable.React
79+
```
80+
81+
### 2. Define the Props
11182

83+
Prop represents the props of the React component. In this recipe, we're using [the props listed here](https://www.npmjs.com/package/react-d3-speedometer) for `react-d3-speedometer`. We model them in Fable.React using a discriminated union.
84+
85+
```fsharp
86+
type Prop =
87+
| Value of int
88+
| MinValue of int
89+
| MaxValue of int
90+
| StartColor of string
91+
```
11292

93+
> One difference to note is that we use **P**ascalCase rather than **c**amelCase.
94+
>
95+
> Note that we can model any props here, both simple values and "event handler"-style ones.
96+
97+
### 3. Write the Component
98+
99+
Add the following function to the file. Note that the last argument passed into the `ofImport` function is a list of `ReactElements` to be used as children of the react component. In this case, we are passing an empty list since the component doesn't have children.
100+
101+
```fsharp
102+
let reactSpeedometer (props : Prop list) : ReactElement =
103+
let propsObject = keyValueList CaseRules.LowerFirst props // converts Props to JS object
104+
ofImport "default" "react-d3-speedometer" propsObject [] // import the default function/object from react-d3-speedometer
105+
```
106+
107+
### 4. Use the Component
108+
109+
With all these in place, you can use the React element in your client like so:
110+
111+
```fsharp
112+
open ReactSpeedometer
113+
114+
reactSpeedometer [
115+
Prop.Value 10 // Since Value is already decalred in HTMLAttr you can use Prop.Value to tell the F# compiler its of type Prop and not HTMLAttr
116+
MaxValue 100
117+
MinValue 0
118+
StartColor "red"
119+
]
120+
```

0 commit comments

Comments
 (0)