Skip to content
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

Root component not hot reloaded when using render #64

Open
RsMan-Dev opened this issue Apr 2, 2024 · 17 comments
Open

Root component not hot reloaded when using render #64

RsMan-Dev opened this issue Apr 2, 2024 · 17 comments

Comments

@RsMan-Dev
Copy link

I have this setup:

globalThis.allComponents = import.meta.glob('/javascripts/components/**/*.{jsx,tsx,js,ts}', {eager: true});

function getComponentByName(name: string) { /* find component by glob **/<name>.{tsx, jsx} */ }

customRender(name:string){
  const Component = getComponentByName(name)
  
  render(() => <Component/>, element)
}

this way, when i edit any child component, hot reload works as expected, but when i make any change to the root component, i have no hot reload.

@lxsmnsyc
Copy link
Member

lxsmnsyc commented Apr 2, 2024

@RsMan-Dev which one is the root component?

if it's the customRender, Solid Refresh doesn't cover it.

@RsMan-Dev
Copy link
Author

i am using the builtin render, the root component is Component @lxsmnsyc

@lxsmnsyc
Copy link
Member

lxsmnsyc commented Apr 2, 2024

@RsMan-Dev then it should work for the components in the your glob. unless it doesn't follow the requirements

@RsMan-Dev
Copy link
Author

RsMan-Dev commented Apr 2, 2024

what are the requirement to follow to have them working? @lxsmnsyc

@RsMan-Dev
Copy link
Author

can you help me @lxsmnsyc ?

Basically, glob is doing this:

globalThis.allComponents = import.meta.glob('/javascripts/components/**/*.{jsx,tsx,js,ts}', {eager: true});
// code produced by vite
import * as __glob__0_0 from './components/Home.tsx'
globalThis.allComponents = {
  './components/Home.tsx': __glob__0_0,
}

When i am rendering Home, it's simply rendering it like:

const Component = allComponents['./components/Home.tsx'].default

//native solidjs's render
render(() => <Component/>, root)

So, i'm basically using native solidjs functions, what is missing to have hot reload working on this code?

@lxsmnsyc
Copy link
Member

lxsmnsyc commented Apr 3, 2024

All of the code you showed are not covered by Solid Refresh.

Show me your Home component and I can give a definite answer.

@RsMan-Dev
Copy link
Author

it's hello, not home on my code:

import { createSignal } from "solid-js";

export default function Hello() {
  const [count, setCount] = createSignal(0);
  return (
    <div>
      <button onClick={() => setCount(count() + 1)}>count: {count()}</button>
    </div>
  );
}

@RsMan-Dev
Copy link
Author

when this code is used inside another component, it's hot reloaded like expected.

@lxsmnsyc
Copy link
Member

lxsmnsyc commented Apr 3, 2024

Then that should work. There's nothing to handle in your root file.

@RsMan-Dev
Copy link
Author

RsMan-Dev commented Apr 3, 2024

another simple reproduction form me:

components/Hello.tsx

import { createSignal } from "solid-js";
import Sub from "./Sub";

export default function Hello() {
  const [count, setCount] = createSignal(0);
  return (
    <div>
      <Sub/>
      <br/>
      <button onClick={() => setCount(count() + 1)}>count: {count()}</button>
    </div>
  );
}

components/Sub.tsx

import { createSignal } from "solid-js";

export default function Sub() {
  const [count, setCount] = createSignal(0);
  return (
    <div>
      <button onClick={() => setCount(count() + 1)}>count: {count()}</button>
    </div>
  );
}

root.ts

import Hello from "./components/Hello";
render(Hello, this)

Here, only Sub is hot reloaded, not Hello, the root component.

@lxsmnsyc
Copy link
Member

lxsmnsyc commented Apr 3, 2024

So what behavior does Hello show when making changes?

@RsMan-Dev
Copy link
Author

nothing changind

@RsMan-Dev
Copy link
Author

vite is trying to hot reload, i receive something on network, but nothing happen in frontend.
idk if it's changing anything, but render is called inside a custom element, on it's "connectedCallback" function.

@RsMan-Dev
Copy link
Author

that's why i'm using "this" as root element

@RsMan-Dev
Copy link
Author

i succeeded to make hot reloading working using this workaround:

components/Root.tsx

interface RootProps { Component: any; props: Record<string, any>;}
export default function Root({Component, props}: RootProps) {
  return <>
    <Component {...props}/>
  </>;
}

components/Hello.tsx

//normal component

root.ts

render(() => <Root Component={component} props={props}/>, this)

here, home is hot reloaded as expected, because not the root component, waiting for your potential fix, i will work using this method.

@lxsmnsyc
Copy link
Member

lxsmnsyc commented Apr 3, 2024

I don't really understand the issue.

Can you perhaps just provide a repro?

@RsMan-Dev
Copy link
Author

When the component is directly rendered using render(), it becomes impossible to hot reload, but when the component is rendered by another component, it becomes hot reloadable

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants