New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[<ReactComponent>] vs React.functionComponent in React refresh #283
Comments
The attribute will be the way to go in the future, and is necessary for react-refresh to work. At least, that's how it was but I thought @Zaid-Ajaj got that sorted out so that there was no difference? |
Hi Roman, This is a really good question to which there is no short answer, here we go. Though once I sort out my internet issues at home, I will resume streaming again where I explain this in excruciating details 😁
First of all, I want to point out that the documentation are in an unfortunate transitional state: basically out of date with latest Feliz and This has to do with how the Javascript code is generated. Now consider this piece of React code: const App = ({ title }) => {
return (
<h1>{title}</h1>
)
};
<App title="My React Application" /> This JS (which is actually JSX) desugars down to the following JS code import { createElement } from 'react'
const App = ({ title }) => {
return createElement("h1", null, title);
};
// <App /> compiles to a call to createElement
createElement(App, { title: "My React Application" }) It is very important to notice that the initialization of the It is important because of two things:
Now, the way let app React.functionComponent("App", fun (props: {| tite: string |}) -> Html.h1 props.title) Is kind-of equivalent to saying let app =
let render(props: {| tite: string |}) =
let renderFn props= Html.h1 props.title
createElement(renderFn , props)
render.displayName <- "App"
render Now this "bad" because This syntax sugar the The solution to these problems is coming in Fable 3 where we are allowed to customize the compilation of the code via compiler plugins. If you consider this F# Feliz code in Fable 3 [<ReactComponent>]
let app (title: string) = Html.h1 title
app "My React Application" Then it compiles down to the equivalent of this JS (not exact because more magic) const App = (props) {
const title = props.title
return createElement("h1", null, title)
}
createElement(App, { title: "My React Application" }) Now this generated code is customized to look like what React tooling expects:
This combination makes React refresh work and by extension makes the experience of Feliz really close to that of native JS or TS. I hope this clears up the confusion. If you have any more questions, just let me know 😉 |
Wow! Just... WOW! Silly person asks stupid question and smart guy answers with three A4 sheets full of relevant information and explanations. 🤯 You just rock, man! Thanks a lot! ❤️ Now I understand and will start using Attribute instead. Is it still recommended to name components somehow (like we did using the first parameter of |
Awesome! Let me if you encounter any problem 😉 right now the only issue to be aware of is using a record type as input props will be just a little bit problematic for React-refresh, so you can use an anonymous record instead or primitive parameters. I am hoping the issue is fixed soon so that I can document
No, the only requirement is that the components are compiled as upper-case values which is one of the things that |
@Dzoukr the only reason to use names for your react components is to make debug tooling better. |
@Shmew Yup, but there is no overload on ReactComponent constructor for adding such name so that's why asked. |
So, continuing the I've got a component that needs to initialize some state. Fortunately, we have many fine hooks available! I write this:
Alas, when I try to run this, my console is sad and full of errors:
I've been through the react debug steps above; none appear to be true. Should this be working? Is this a Fable 3 only thing? (I'm still using Fable 2.) |
My understanding is that the reactcomponent attribute needs fable 3 to work because it is a fable 3 compiler plugin |
@landy ah, that'd sure do it. Lemme get Fable 3 working, will report back in a minute |
Hey! Yep, that fixed me -- I used this PR as a guide for the conversion. |
Hello friend,
as naive wannabe frontend dev I came into interesting behavior:
Based on your docs, I favour using
React.functionComponent
to create components because I can also specify the name of component for better debuging. Funny thing comes with react refresh.Code like this always trigger full page reload when doing any change in code:
But having root component with
[<ReactComponent>]
will make all refresh working great without doing full refresh.Is it bug? Is it bug in fancy black tie aka feature? Is it all my fault because I don't get the difference between ReactComponent attribute and React.functionComponent function? 😄
Thanks for any kind of help to better understand.
The text was updated successfully, but these errors were encountered: