fable-compiler / fable-react

Fable bindings and helpers for React and React Native
MIT License
273 stars 67 forks source link

add 'contextConsumer' #165

Closed 0x53A closed 5 years ago

0x53A commented 5 years ago

closes https://github.com/fable-compiler/fable-react/issues/164

Note: this is currently completely untested.

0x53A commented 5 years ago

It currently works on the client side, but not in SSR:

let ctx = createContext("de")

let inline consume() = contextConsumer ctx (fun lang -> str lang)

// ...

let view model =

// ...

                str "This should be the default value (de):"
                consume()
                contextProvider ctx model.Language [
                    str (sprintf "This should be the model value (%s):" model.Language)
                    consume()
                    contextProvider ctx "xyz" [
                        str (sprintf "This should be the overridden value (%s):" "xyz")
                        consume()
                    ]
                    str (sprintf "This should be the model value (%s):" model.Language)
                    consume()
                ]
                str "This should be the default value (de):"
                consume()

Clientside:

image

SSR:

image

I think it renders the elements too early, so that my stack pushing/popping is completely useless ...

Since SSR is currently incorrect, anyway, this is not a regression, so i think I'll revert that part and just PR the new 'contextConsumer' function.

What do you think?

alfonsogarciacaro commented 5 years ago

This is due to my "cheap solution" in order to support the context API in .NET without many code changes. As it's currently difficult to pass a context object through the nested rendered elements in SSR, I'm just using the default value and hoping the proper one will be used on the client side when mounting React. Does it happen like this in your example?

Maybe it'd be better to fix it in SSR (your note in the comment is already helpful!) but I'm not sure what would be the easiest way to do this. Any ideas?

In any case, thanks for the PR!

0x53A commented 5 years ago

'm just using the default value and hoping the proper one will be used on the client side when mounting React. Does it happen like this in your example?

Yes, after the first client-side render all is ok.

In my use-case (localization) it doesn't matter anyway, there is only one context anyway.

Maybe it'd be better to fix it in SSR (your note in the comment is already helpful!) but I'm not sure what would be the easiest way to do this. Any ideas?

No simple idea, the rendering would need to be delayed so that the parent can influence the child.

alfonsogarciacaro commented 5 years ago

Ok, if the client side fixes this let's consider it good enough for now ;) Released as 5.2.4, thank you!