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

prefresh-vite is not preserving the state of a component #543

Closed
SuperDisk opened this issue Apr 26, 2024 · 12 comments
Closed

prefresh-vite is not preserving the state of a component #543

SuperDisk opened this issue Apr 26, 2024 · 12 comments

Comments

@SuperDisk
Copy link

I'm making my own prefresh integration for fun, and I decided to compare the behavior of mine to a known working implementation so I could verify how it works. My custom integration (done by basically following the blog post and reading a bit of the prefresh-vite code) works, and when I update a component it preserves state unless I add or remove hooks.

I tried prefresh-vite however and it's actually not working-- I created a sample application with npm init preact and put this code in index.jsx:

import { render } from 'preact';
import {useState} from 'preact/hooks';

export function App() {
  const [ctr, setCtr] = useState(0);
  return (
    <div>
      <p>The counter: {ctr}</p>
      <button onClick={() => setCtr(ctr+1)}>Increment</button>
    </div>
  );
}

render(<App />, document.getElementById('app'));

When I modify something (like just changing some text inconsequentially) it instantly updates in the browser but also resets the counter to 0 every time. I'm not sure what's happening, I put a breakpoint in flushUpdates and it doesn't throw an exception (I don't think).

@JoviDeCroock
Copy link
Member

Hey, it's been a while since I looked at this repo. I tried running the tests which fail on full browser reload as well as made a new vite app with Preact and it worked. Do you have a repro or do you want to work on a fix?

@SuperDisk
Copy link
Author

SuperDisk commented Apr 27, 2024

Hmm, so you couldn't reproduce it? The code above is pretty much it. Here's the behavior I'm seeing:

prefresh-.2.mp4

My vite.config.js is the default:

import { defineConfig } from 'vite';
import preact from '@preact/preset-vite';

// https://vitejs.dev/config/
export default defineConfig({
	plugins: [preact()],
});

@SuperDisk
Copy link
Author

I just tried creating a Preact app with preact-cli (which I think uses webpack?) and the behavior there seems to work-- that is, updating the code doesn't reset the counter. So it's potentially an issue with the Vite integration?

@JoviDeCroock
Copy link
Member

JoviDeCroock commented Apr 27, 2024

npm init preact creates a vite one which seemed to work, your vite configuration should work unless you have to explicitly enable prefresh. Or it's a bug in a recent vite version

@SuperDisk
Copy link
Author

What does npx vite --version show for you in your npm init preact project?

@JoviDeCroock
Copy link
Member

Not at home atm but the tests use v5 https://github.com/preactjs/prefresh/blob/main/test/fixture/vite/package.json that being said, let's not make this issue a debugging session. I can either look at it in the next few weeks or as you have a working impl feel free to look into it

@JoviDeCroock
Copy link
Member

Just got back to this seems to work just fine on #544

@SuperDisk
Copy link
Author

FWIW this still doesn't work for me with a freshly generated npm init preact project. I also changed vite to latest in package.json and it has the same problem.

@JoviDeCroock
Copy link
Member

Mind creating a reproduction then?

@SuperDisk
Copy link
Author

preact-reproducer.zip

For me, when I modify anything in index.jsx, the whole state gets reset.

@JoviDeCroock
Copy link
Member

JoviDeCroock commented May 19, 2024

But that's the function that contains render, that's expected because as mentioned in the memory leak issue, ESM HMR creates a new copy of the file. Also creating a repro in stackblitz etc makes it a lot easier to talk about.

i.e. if I move your Counter to a new file, that does not contain render() everything works just fine.

@SuperDisk
Copy link
Author

Yep you're right, sorry for the confusion. I guess looking back it should have been obvious that HMR is re-executing all that stuff. Thanks.

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