Feliz
Feliz copied to clipboard
ReactComponent attribute does not work without calling `ofFunction` where used
So I am having a strange issue with Feliz 1.68 and Fable 3.7.1.
I'm trying to author React components. When I just add the [<ReactComponent>]
attribute to an F# function with a capital name and a list of properties (which is usually empty), I'm expecting it to generate a React Function Component. But the generated component's logic is essentially comprised of constructing arrays like what's in the F# code. Which is fine, except my React components don't work.
In every example I've seen, all I am supposed to need is the ReactComponent Attribute and supposedly I'd get a function component, and then I can just call that component like a function. But when I do that, I get this error:
Invalid hook call. Hooks can only be called inside of the body of a function component.
And the generated code looks like this:
export function Router() {
let elements;
const patternInput = Feliz_React__React_useState_Static_1505(RouterModule_urlSegments(window.location.hash, 1));
const updateUrl = patternInput[1];
const currentUrl = patternInput[0];
return RouterModule_router(createObj(ofArray([["onUrlChanged", updateUrl], (elements = toList(delay(() => {
const matchValue = Url_Parse_1334CEF1(currentUrl);
switch (matchValue.tag) {
case 1: {
return singleton(createElement("h1", {
children: ["Logging In..."],
}));
}
case 0: {
return singleton(Index());
}
case 2: {
return singleton(Estimator());
}
case 3: {
return singleton(TimeTracker());
}
default: {
return singleton(createElement("h1", {
children: ["Error 404: Not Found"],
}));
}
}
})), ["application", react.createElement(react.Fragment, {}, ...elements)])])));
}
export function PageContainer() {
let elems_5, elms_1, elms, props_2, elems_2, elms_2, props_6, elems_3;
const props_9 = ofArray([["className", "is-fullheight"], (elems_5 = [(elms_1 = singleton_1((elms = singleton_1(Navbar()), createElement("div", {
className: "container",
children: Interop_reactApi.Children.toArray(Array.from(elms)),
}))), createElement("div", {
className: "hero-head",
children: Interop_reactApi.Children.toArray(Array.from(elms_1)),
})), (props_2 = singleton_1((elems_2 = [Router()], ["children", Interop_reactApi.Children.toArray(Array.from(elems_2))])), createElement("div", createObj(Helpers_combineClasses("hero-body", props_2)))), (elms_2 = singleton_1((props_6 = ofArray([["className", "is-fluid"], (elems_3 = [createElement("div", createObj(Helpers_combineClasses("content", ofArray([["className", "has-text-centered"], ["children", "© 2022 General Digital Corporation"]]))))], ["children", Interop_reactApi.Children.toArray(Array.from(elems_3))])]), createElement("div", createObj(Helpers_combineClasses("container", props_6))))), createElement("div", {
className: "hero-foot",
children: Interop_reactApi.Children.toArray(Array.from(elms_2)),
}))], ["children", Interop_reactApi.Children.toArray(Array.from(elems_5))])]);
return createElement("section", createObj(Helpers_combineClasses("hero", props_9)));
}
export function App(pca) {
const props = ofArray([["instance", pca], ["children", [PageContainer()]]]);
return Interop_reactApi_1.createElement(msalProvider, createObj(props));
}
render(App(createClient(Msal_config)), document.getElementById("elmish-app"))
In order to get anything to work at all, I have to use the ofFunction
function everywhere I use a ReactComponent, which I thought the attribute was supposed to do for me. Then, the generated code looks like this:
export function Router() {
let elements;
const patternInput = Feliz_React__React_useState_Static_1505(RouterModule_urlSegments(window.location.hash, 1));
const updateUrl = patternInput[1];
const currentUrl = patternInput[0];
return RouterModule_router(createObj(ofArray([["onUrlChanged", updateUrl], (elements = toList(delay(() => {
const matchValue = Url_Parse_1334CEF1(currentUrl);
switch (matchValue.tag) {
case 1: {
return singleton(createElement("h1", {
children: ["Logging In..."],
}));
}
case 0: {
return singleton(react.createElement(Index, void 0));
}
case 2: {
return singleton(react.createElement(Estimator, void 0));
}
case 3: {
return singleton(react.createElement(TimeTracker, void 0));
}
default: {
return singleton(createElement("h1", {
children: ["Error 404: Not Found"],
}));
}
}
})), ["application", react.createElement(react.Fragment, {}, ...elements)])])));
}
export function PageContainer() {
let elems_5, elms_1, elms, props_6, elems_2, elms_2, props_10, elems_3;
const props_13 = ofArray([["className", "is-fullheight"], (elems_5 = [(elms_1 = singleton_1((elms = singleton_1(react.createElement(Navbar, void 0)), createElement("div", {
className: "container",
children: Interop_reactApi.Children.toArray(Array.from(elms)),
}))), createElement("div", {
className: "hero-head",
children: Interop_reactApi.Children.toArray(Array.from(elms_1)),
})), (props_6 = singleton_1((elems_2 = [react.createElement(Router, void 0)], ["children", Interop_reactApi.Children.toArray(Array.from(elems_2))])), createElement("div", createObj(Helpers_combineClasses("hero-body", props_6)))), (elms_2 = singleton_1((props_10 = ofArray([["className", "is-fluid"], (elems_3 = [createElement("div", createObj(Helpers_combineClasses("content", ofArray([["className", "has-text-centered"], ["children", "© 2022 General Digital Corporation"]]))))], ["children", Interop_reactApi.Children.toArray(Array.from(elems_3))])]), createElement("div", createObj(Helpers_combineClasses("container", props_10))))), createElement("div", {
className: "hero-foot",
children: Interop_reactApi.Children.toArray(Array.from(elms_2)),
}))], ["children", Interop_reactApi.Children.toArray(Array.from(elems_5))])]);
return createElement("section", createObj(Helpers_combineClasses("hero", props_13)));
}
export function App(pca) {
const props_2 = ofArray([["instance", pca], ["children", [react.createElement(PageContainer, void 0)]]]);
return Interop_reactApi_1.createElement(msalProvider, createObj(props_2));
}
render(App(createClient(Msal_config)), document.getElementById("elmish-app"));
This works, but now I get a different set of warnings that I have no idea how to resolve:
Each child in a list should have a unique "key" prop.
I don't know how to add a key prop, because I need to return ReactElement
and props are IReactProperty
.
Also, as an aside, what are the benefits of moving to Fable 4 + Feliz 2 in terms of writing a React program?