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
version 3 loses component local state #276
Comments
If you want to keep the local state of a
Does this make sense?
It patches |
This is the accordion component that I was tweaking, and it's not a connected component: https://gist.github.com/jlongster/5d97bac8c9d776d12a7e8b2c17a6b3af The component which creates the accordion, however, is: https://gist.github.com/jlongster/204d05ca52874d099ea4ecf34ca23c15 I don't quite understand how the new version works though, so I might still be missing something. |
Aha. It seems like the same problem as #275 (comment). We patch Can you try replacing require('react-hot-loader/patch') with require('react-hot-loader/patch')
require('react/lib/ReactElement').createElement = require('react').createElement ? |
Filed as #277, this is the most likely culprit. |
I was including the patch as a webpack entry, but I removed that and added both lines to the top of my I'd poke around some more to help with this but I don't have a whole lot of time. Any idea why it would create an infinite loop? |
Ugh, you’re right. There’s some tricky dependency stuff going on there. This is the stack: I can’t say for sure, but in any case monkeypatching internal modules is a bad idea.
We need to patch If you’d like to help, feel free to copy paste this test case, call it |
Alright, thanks for looking into it! I would love to help but I'm a little tight on time right now. I just noticed something odd. I tried version 1.3.0 and I'm actually still seeing the behavior of the accordion collapsing. It looks like the state is being reset with the old version too, so while I may have highlighted a problem with the new version, I may be doing something wrong. I don't really know, the old version usually worked for me, so I'll have to look into what's up. |
Got it. Let’s keep it open for now until we know the root cause. |
@jlongster any way can you see whether you still have this issue? |
Gonna close this out because I haven't heard back. Please re-open if you're still having the same issue! |
https://github.com/Glavin001/react-hot-ts, as recommended by https://github.com/gaearon/react-hot-loader/tree/master/docs, is still losing internal state. Is it because of the fact that it uses purely
|
@truongsinh: I don't know understand the semantics of |
Thank you for the reference. export default class Counter extends Component {
constructor(props) {
super(props);
this.state = { counter: 0 };
}
componentDidMount() {
this.interval = setInterval(this.tick.bind(this), 1000);
}
tick() {
this.setState({
counter: this.state.counter + 1
});
}
componentWillUnmount() {
clearInterval(this.interval);
}
render() {
return (
<h2>Counter: {this.state.counter}</h2>
);
} But the const webpack = require("webpack");
const path = require("path");
module.exports = {
entry: [
"react-hot-loader/patch",
"webpack-dev-server/client?http://localhost:3000",
"webpack/hot/only-dev-server",
"./src/index.tsx",
],
output: {
path: path.join(__dirname, 'dist'),
filename: "bundle.js",
publicPath: "/static/",
},
// Enable sourcemaps for debugging webpack's output.
devtool: "source-map",
resolve: {
// Add '.ts' and '.tsx' as resolvable extensions.
extensions: ["", ".webpack.js", ".web.js", ".ts", ".tsx", ".js"]
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify('production')
}
}),
new webpack.HotModuleReplacementPlugin(),
],
module: {
loaders: [
// All files with a '.ts' or '.tsx' extension will be handled by 'ts-loader'.
{
test: /\.tsx?$/,
loaders: [
"react-hot-loader/webpack",
"awesome-typescript-loader"
],
exclude: path.resolve(__dirname, 'node_modules'),
include: path.resolve(__dirname, "src"),
}
],
preLoaders: [
// All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
{ test: /\.js$/, loader: "source-map-loader" }
]
},
// When importing a module whose path matches one of the following, just
// assume a corresponding global variable exists and use that instead.
// This is important because it allows us to avoid bundling all of our
// dependencies, which allows browsers to cache those libraries between builds.
externals: {
"react": "React",
"react-dom": "ReactDOM"
},
}; |
For anyone who runs in to this, the solution for typescript for myself was to change the typescript loader to include See also: |
TLDR: don't use Just wanted to report what was the problem in my case causing local state to be lost with RHL3: Solution for us: Note for point of interest: we were, and still are, wrapping our App export in an |
Okay after fixing the problem above I realised a HOC we created ourselves breaks the HMR in the same way (always gets remounted so local state is always lost), I'm not quite getting why - if anyone has ideas: |
Did you @pocketjoso manage to fix this by any chance? I have quite a few HOC composed to get my final component and I am pretty sure I am hitting the same limitation. I could theoretically move the hoc functionality to some utils to (maybe) fix this, but damn, it should work with HOC as well. Shouldn't it? |
@PeterKottas With HOC - yes, with double HOC-no. |
Hi @theKashey. My code looks something like this.
The rooms component itself is a default export from a file and it's also connected to redux store. After reading bunch of issues here, it seems like what I have is a bit of a nightmare case. Btw, withDashboardLayout is just an lambda component implemented like this.
I wonder if this would be causing problems as well. The rest of them are proper HOC. |
It might also be worth pointing out I am using typescript and awesome-typescript-loader to transpile. Setup is based on docs. Nothing special there. |
@PeterKottas - let me reveal the hidden truth const roomsWrapped =
withDashboardLayout( // produces a result
rolesLoadedHoc( // produces a temporary variable
propertyPlanLoadedHoc( // produces a temporary variable
roomsLoadedHoc( // produces a temporary variable
Rooms // a variable.
)))); So - here we hot 3 temporal classes, RHL can not manage. |
Cool, that makes perfect sense. But it's still quite a problem for me :( Not exactly sure how to approach it as: was this always a no no with hmr? I could have sworn this was working at some point in time. For dev experience, I guess I could fake the initial state to "working state" to allow me to work with HMR, it's a bit of a pain though |
I have an accordion that has local state that tracks which panes are open. When I update one of the panes, the open panes collapse because (I'm assuming) the accordion's state is being set back the default state.
There are many moving pieces so I'm not sure what to point out. I'm using webpack-dev-middleware, webpack-hot-middleware, and my config looks like this:
My component files are definitely being transformed, here is a snippet:
Finally, how I render the root component:
Looking at AppContainer, I don't see where it would save local state. I'm requiring the new version of
TabList
which ends up requiring the new version of my component, and it appears to just be re-rendering my whole app with the new component, and I don't see where state is transferred across these instances.The text was updated successfully, but these errors were encountered: