Simplify function component creation #2289
Replies: 3 comments 4 replies
-
If people are happy with this, I can work out a proof of concept in a different repo. Maybe I'll call it |
Beta Was this translation helpful? Give feedback.
-
Regarding your proposalI am really not a fan of the proposed api as everything gets jumbled all together. Double naming issueI think this could be solved by just overriding the function name inside the macro, though im not sure why its not done like this already #[function_component]
pub fn MyComponent() -> Html {
html! {
<div></div>
}
} we could even go one step further and provide a optional #[fc]
pub fn MyComponent() -> Html {
html! {
<div></div>
}
} Props and snippetsPersonally i love having Props as a separate structure outside the component, but it just probably comes from me using a lot of react with typescript in the past. #[function_component(MyComponent)]
pub fn my_component(fc_props!{
prop_a: &'static str,
#[prop_or_default]
prop_b: i8,
#[prop_or(42)]
prop_c: u8,
#[prop_or_else(my_fn)]
prop_d: bool,
}) -> Html {
html! {
<div></div>
}
} in this case even your approach works #[function_component(MyComponent)]
pub fn my_component(fc_props!{
prop_a: &'static str,
prop_b: i8 or default,
prop_c: u8 or 42,
prop_d: bool or else my_fn,
}) -> Html {
html! {
<div></div>
}
} For generics you would need to fallback to making a separate struct Final lookit looks like so if combining all my proposals: #[fc]
pub fn MyComponent(fc_props!{
prop_a: &'static str,
prop_b: i8 or default,
prop_c: u8 or 42,
prop_d: bool or else my_fn,
}) -> Html {
html! {
<div></div>
}
} |
Beta Was this translation helpful? Give feedback.
-
I would like the function component be just functions. No macro or trait required. fn FunctionComponent(props: &Props) -> Html {
todo!()
} This can be made possible by the following implementation: impl<T> FunctionProvider for T
where
T: Fn(...) -> Html
{
/// ...
} Of course, this would trip up lints, but that could be disabled. |
Beta Was this translation helpful? Give feedback.
-
Function component has a simpler syntax compared to struct components, but it still has a lot of boilerplate. The snake-case function name (as opposed to the PascalCase component name) is redundant. And it's the worse when you have a generic component, where the generic argument and the trait bound have to be repeated in three places.
Simply adding templates to IDE has its own problems. It's common to use a mix of function components both with and without property. And it's common to convert from one to another. Converting a property-less component to a property-ful component requires a lot of typing and thinking.
I want to propose a simpler and powerful function proc-macro
comp!
with which you can add or remove properties as you go, and which requires no code duplication at all. The syntax is:Here are a few examples:
Component with no properties
before:
after:
Component with properties:
before:
after (ahhhhhh, so elegant, so much better):
Note the or, default, and else are now custom keywords. Implementation-wise, it should be possible to distinguish the component body from the props by peeking
ident : type
syntax, because I don't think it's valid to have this syntax in a function body.Generic Components
before (gotta repeat
<T: Clone>
three times, ew):after (noice):
What's Implied
MyComponentProps
will be generated. It only derivesPartialEq
andProperties
and users can't add other derives.I don't see this as an inconvenience because, in my experience with
yew
, I've never felt a need to have other derives.I might have missed some use cases though. I'm not against adding a custom derive syntax to the macro.
The snake case function with the name
my_component
will be generated from the PascalCase component name. If properties are present, the users should understand that aprops
argument is injected by the macro and that they can use theprops
variable in the component body section of the macro.Beta Was this translation helpful? Give feedback.
All reactions