solid-start icon indicating copy to clipboard operation
solid-start copied to clipboard

[Feature?]: Improve ergonomics of `clientOnly` function with a helper.

Open MengLinMaker opened this issue 1 year ago • 3 comments

Duplicates

  • [X] I have searched the existing issues

Latest version

  • [X] I have tested the latest version

Summary 💡

According to solid-docs-next/issues/840, clientOnly requires at least 2 files wit the use of import()

However, this is quite inconvenient for experimenting with CSR vs SSR.

So I'd like to propose a wrapper which is much simpler to use.

Examples 🌈

The useClient wrapper could be implemented in this way:

import { clientOnly } from '@solidjs/start'
import { Component } from 'solid-js'

// Client side render wrapper
type ResolveClientComponent<T> = (value: {
  default: Component<T>
}) => void

export const useClient = <T,>(App: Component<T>) => {
  return clientOnly(() => {
    return new Promise((resolve: ResolveClientComponent<T>) => {
      resolve({ default: App })
    })
  })
}

Usage:

const ComponentSSR =() => { ... }

const ComponentCSR = useClient(() => { ... })

Motivation 🔦

This feature allows quick switching between client side rendering or server side rendering without the overhead of adding additional files and import.

MengLinMaker avatar Sep 02 '24 15:09 MengLinMaker

I don't think this merits being a built-in primitive.

One can also do this and is a lot simpler:

import { onMount, createSignal, Show } from 'solid-js';

function clientComponent<T>(Comp: Component<T>): Component<T> {
  return function (props: T) {
    const [flag, setFlag] = createSignal(false);
    
    onMount(() => setFlag(true));
    
    return <Show when={flag()}><Comp {...props} /></Show>;
  }
}

You know what, I'll add this to solid-use/client-only

lxsmnsyc avatar Sep 02 '24 16:09 lxsmnsyc

Plus you don't need 2x files you can just export from the same file like:

//my-component.tsx
export default function MyComponent() {
//...
return "Some JSXElement"
}


export const MyClientOnlyComponent = clientOnly( () => import("./my-component") )

madaxen86 avatar Sep 03 '24 13:09 madaxen86

I don't think this merits being a built-in primitive.

One can also do this and is a lot simpler:

import { onMount, createSignal, Show } from 'solid-js';

function clientComponent<T>(Comp: Component<T>): Component<T> {
  return function (props: T) {
    const [flag, setFlag] = createSignal(false);
    
    onMount(() => setFlag(true));
    
    return <Show when={flag()}><Comp {...props} /></Show>;
  }
}

You know what, I'll add this to solid-use/client-only

This gives me a 'Hydration Mismatch' error

g-mero avatar Sep 10 '24 07:09 g-mero