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

Lose state while using TypeScript without Babel #923

Closed
nonoroazoro opened this issue Apr 2, 2018 · 17 comments
Closed

Lose state while using TypeScript without Babel #923

nonoroazoro opened this issue Apr 2, 2018 · 17 comments

Comments

@nonoroazoro
Copy link

nonoroazoro commented Apr 2, 2018

Environment (without Babel):

  1. [email protected]
  2. [email protected]
  3. [email protected]
  4. [email protected]
  5. [email protected]
  6. [email protected]
  7. [email protected]
  8. [email protected]

Expected behavior

HMR with state preserved.

Actual behavior

HMR worked, while the state is lost.

Upgraded Environment (with Babel):

  1. add [email protected]
  2. add [email protected]
  3. add react-hot-loader/babel in .babelrc

Now I get HMR with state preserved, but I really don't want to add Babel to my TypeScript project.

What I expected is to have a full HMR without adding Babel. Are there ways around this? Thanks!

@gregberge
Copy link
Collaborator

For now we rely on Babel to make React Hot Loader work. I am sorry, but you have to add Babel if you want to use it.

@theKashey
Copy link
Collaborator

Babel is not required to preserve the state, only to properly propagate updates.
Something else is wrong(may be setup?), but I could not help without actual code

@nonoroazoro
Copy link
Author

nonoroazoro commented Apr 2, 2018

@theKashey Yeah really? Maybe I made mistakes some where. I'm really appreciate if you have time to help checking the code!

Here's it: https://github.com/nonoroazoro/typescript-react-boilerplate

You can run npm i && npm run dev to start the app at localhost:8080.

I've put a button on the page, you can click it and then modify App.tsx to reproduce the result. You'll find that the value of the state is lost right after the update.

@nonoroazoro
Copy link
Author

@neoziro Thanks anyway!

@theKashey
Copy link
Collaborator

Your code is 100% fine. It does not work due some optimizations I've added :(
React-hot-loader does not understand that something got updated and does not try to perform an update.

How to solve? Add to the ./components/App(file you are expecting changes from)

require('react-hot-loader').default.register(() => {}, 'a','b');

Anywhere. This code will just got executed on hot-module-replacement, and inform RHL about that event.

Look like it is time to bring back webpack loader :)

@nonoroazoro
Copy link
Author

nonoroazoro commented Apr 3, 2018

@theKashey Got it. I'll try this and wait for your good news. Thanks again for helping me understanding this issue~ 😸

You're right, it's worked!!! 😆

@theKashey
Copy link
Collaborator

Even better - you can add this code to the index.tsx. Just right before ReactDOM.render

@nonoroazoro
Copy link
Author

Yep, I'll do it :)

@pleerock
Copy link

pleerock commented Apr 5, 2018

@nonoroazoro did you get it working? Im interested in this issue as well.

@theKashey
Copy link
Collaborator

I've just played with your example, and fixed it with 3 lines, I've added to App.tsx (no changes in index.tsx)

import {hot} from 'react-hot-loader';
...... // all the file

declare const module: any;
export default hot(module)(App);

@nonoroazoro
Copy link
Author

nonoroazoro commented Apr 5, 2018

@pleerock Yes it worked~ and I've put some comments about the HMR in my source code.

@theKashey Thanks again! 😄 Actually I've already seen this api while I'm searching for the register function. The reason why I didn't use hot is because I got a using private name 'App' error from TypeScript compiler, and I didn't find a proper solution 😭

Screenshot:
2018-04-05_200947

@theKashey
Copy link
Collaborator

export class App -> I have to idea why, but TS expect you to reexport used class.

@pleerock
Copy link

pleerock commented Apr 5, 2018

Would be great to support this out of the box, there are lot of people using typescript that will face this problem

@theKashey
Copy link
Collaborator

We can’t. If we will try to hot reload code on each render - it will ruin everything.
We need some signal to rely on, for example - ‘hot’ method.

@nonoroazoro
Copy link
Author

nonoroazoro commented Apr 5, 2018

export class App did solve the problem, but I don't quite like it... haha

@nonoroazoro
Copy link
Author

@theKashey I finally solved the using private name 'App' error by applying hot as Decorators:

// Add hook to auto re-render the root component.
@hot(module)
export default class App extends PureComponent
{
    render()
    {
        return (
            <div className={styles.app}>
                <Counter />
            </div>
        );
    }
}

In addition, it also solved the state lost problem... I can safely remove the register api from my index.ts file now.

It's perfect! I love this hot api, thanks a lot for your great work! 😄

@theKashey
Copy link
Collaborator

Ok. I should update Readme :)

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

4 participants