elmish / react

Elmish React extensions for writing SPA and Native apps
https://elmish.github.io/react
Other
104 stars 21 forks source link

Elmish React Native update / view sync problem when init has Cmd #90

Open playfulThinking opened 9 months ago

playfulThinking commented 9 months ago

Description

I have an React Native app (using Expo) that queues up a Cmd in the init function passed to Program.mkProgram. The Cmd does get executed in update before the first view call, but, weirdly, view gets the previous state.

Repro code

I made a minimal repro, following the counter example, modified to include a Cmd at startup:

let init () = 0, Cmd.ofMsg Increment

let update (msg:Msg) count =
    console.log "IN UPDATE"
    match msg with
    | Increment -> count + 1, Cmd.none
    | Decrement -> count - 1, Cmd.none

let Render model dispatch =
    console.log $"IN RENDER, state = {model}"
    JSX.jsx $"""
        import {{View, Text, Button}} from 'react-native'        
        <View>
            <Text>{model}</Text>
            <Button title="Increment" onPress={fun _ -> dispatch Increment} />
            <Button title="Decrement" onPress={fun _ -> dispatch Decrement} />
        </View>
    """ |> toReact 

 Program.mkProgram init update Render
        |> Program.withConsoleTrace
        |> Program.withReactNative "main"
        |> Program.run

Expected and actual results

I expected Render to show a '1'; instead, it shows '0'.

Here's the trace:

 LOG  Initial state: 0
 LOG  Updated subs: []
 LOG  New message: "Increment"
 LOG  IN UPDATE
 LOG  Updated state: 1
 LOG  Updated subs: []
 LOG  IN RENDER, state = 0

This code works when run on the web (using React Native Web) with

 Program.mkProgram init update Render
        |> Program.withConsoleTrace 
        |> Program.withReactBatched "root"
        |> Program.run

Related information

Thanks much!

et1975 commented 9 months ago

Thanks for the report. It's been a long time since I had React Native tooling setup and we didn't have Expo integration back then, so I don't have a good feel for what to look at. I'd start by looking at the generated sources to see how it aligns with Expo's samples, maybe some clue will show up.

playfulThinking commented 9 months ago

Thanks very much for your quick response. I appreciate any response, esp. since I'm sure practically no one is using Elmish in React Native!

I'll let you know if I figure something out. In the meantime I can work around the problem.

Best.