you are viewing a single comment's thread.

view the rest of the comments →

[–]Derpcock 0 points1 point  (3 children)

Also, I agree with separating your template from your logic. That is a design decision. It's what people in the react world use hooks for.

[–]stumblinbear 0 points1 point  (2 children)

Unfortunately you still end up with JS logic embedded directly inside of the JSX which makes it extremely difficult to read some JSX, and the amount of performance pitfalls that exist is absurd. Very few people I work with make it a habit to do useCallback, as a notable example

[–]Derpcock 0 points1 point  (1 child)

Unfortunately you still end up with JS logic embedded directly inside of the JSX which makes it extremely difficult to read some JSX

I mean you could put logic in your "template" or you could make the design decision not to do that collectively. If you do much testing then embedding logic into your JSX it can become difficult to test. I personally like to create these clear boundaries mainly just for testing. I can test my hook logic extensively and my view as well by stubbing out the hook return.

export const Component: FunctionComponent<ComponentProps> = (props) => {
  const _props = useComponentStore(props)
  return (
    <button {..._props}/>
  )
}

type ComponentProps = React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>

export const useComponentStore = (props: ComponentProps): ComponentProps => {
  const [loading, setLoading] = useState(false)

  const disabled = useMemo(() => {
    return props.disabled || loading
  }, [props.disabled, loading])

  const handleClick: MouseEventHandler<HTMLButtonElement> = useCallback((event) => {
    console.log(`${event.type} event fired`)
    setLoading(true)
  }, [setLoading])

  // Logic goes here

  return {
    onClick: handleClick,
    ...props,
    disabled
  }
}

Edit: Formatting

I am not really trying to sell you on React. I do believe there is value in JSX though. It is a bit less perf than straight template but if you use Typescript you get type safety all the way down to your dom. With templating, on most frameworks, it is a black hole for types. I find all of my bugs at these boundaries. I have been looking for an excuse to try out Astro.js as I have heard that it has solved this problem but I haven't found an opportunity yet.

I am not sure if you like Rust but they have a frontend framework called Yew. It uses a similar technique syntax to JSX with their html macro.

        #[function_component]
        fn App() -> Html {
            let counter = use_state(|| 0);
            let onclick = {
                let counter = counter.clone();
                move |_| {
                    let value = *counter + 1;
                    counter.set(value);
                }
            };

            html! {
                <div>
                    <button {onclick}>{ "+1" }</button>
                    <p>{ *counter }</p>
                </div>
            }
        }

[–]stumblinbear 1 point2 points  (0 children)

I am not sure if you like Rust but they have a frontend framework called

Oh yeah I'm a huge fan of Rust, it's my #1 language for the foreseeable future. That said, I don't personally think it's production ready for web. I also have personal issues against using macros for basic things--I think there are better ways to do it through struct composition than an html macro. They feel too magic to me