elmish-to-react

0.0.2 • Public • Published

elmish-to-react

Wrap an Elmish program as a React component.

This is helpful when writing a React app that needs to render an Elmish program as a reuseable component.

A basic example

Step 1: Write a Elmish program in F#

Follow the Elmish basic instructions to build your program in F#.

let myProgram = Program.mkProgram init update view

Step 2: Wrap your program into a React component

open Fable.Elmish.ElmishToReact
let MyProgramComponent = elmishToReactSimple myProgram

Step 3: Start using your component

From your javascript/react code you can render your wrapped program just like any regular React component:

const WrapperComponent = (props) =>
  <div>
    <p>Here's the wrapped program:</p>
    <MyProgramComponent/>
  </div>
 
ReactDOM.render(<WrapperComponent/>, element);

Passing Props

In React we like to pass props into child components. The child should re-render when there is a change in the props it receives from the parent.

How can we pass in props to our Elmish program and trigger a re-render?

Let's rewrite our program so it is ready to receive props. The props includes a label string and a saySomething function is used to pass information from the child back up the parent.

type Props =
  abstract label : string
  abstract saySomething : string -> unit
 
type Model =
  { Props : Props
    // ...plus any other model attributes you need
  }
 
type Msg =
  | UpdateProps of Props
  // ...plus any other Msg types you need
 
let init props =
  { Props = props }, Cmd.none
 
let update msg model =
  match msg with
  | UpdateProps props ->
      { model with Props = props }, Cmd.none
 
let program = Program.mkProgram init update view

Next we "externalise" our program. This allows us to externally feed a props message into the Elmish program:

open Fable.Elmish.ElmishToReact
 
let externalisedProgram =
  Externalised.externalise program
  |> Externalised.withPropsMsg UpdateProps
 
let MyProgramComponent = elmishToReact externalisedProgram

In our javascript code we can pass the props into our wrapped program:

ReactDom.render(
    <MyProgramComponent label="Hello, world"
                        saySomething={(msg) => console.log(msg)}/>,
  element)

Unmounting

React might need to repeatedly mount and unmount the Elmish program as the user navigates around a single page app. The Elmish program might want to clean-up its resources each time it is unmounted.

Let's rewrite our program so it can receive an unmount message:

type Msg =
  | Unmount
  // ...plus any other Msg types you need
 
let update msg model =
  match msg with
  | Unmount ->
      // Do any clean-up here
      model, Cmd.none
 
let program = Program.mkProgram init update view

Next we add the Unmount message to our externalised program.

open Fable.Elmish.ElmishToReact
 
let externalisedProgram =
  Externalised.externalise program
  |> Externalised.withUnmountMsg Unmount
 
let MyProgramComponent = ElmishComponent.elmishToReact externalisedProgram

A complete example

Example.fs contains a example of an Elmish program demonstrating all the features described above.

example.js is an example of calling the elmish program with react syntax.

To run the example....

yarn run start

...and open http://localhost:8080 in your web browser

Installation with npm

npm install --save-dev elmish-to-react
dotnet add reference ./node_modules/elmish-to-react/Fable.Elmish.ElmishToReact.fsproj
dotnet restore

Installation with paket

paket add nuget Fable.Elmish.ElmishToReact -i

Readme

Keywords

Package Sidebar

Install

npm i elmish-to-react

Weekly Downloads

0

Version

0.0.2

License

MIT

Unpacked Size

42.8 kB

Total Files

8

Last publish

Collaborators

  • istreeter