-
Notifications
You must be signed in to change notification settings - Fork 802
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
Hot Reload doesn't work when starting inside a function #765
Comments
Yet again. You shall mark as HOT EXPORTS of a module. Not imports. So - just extract App into separate file, end |
@theKashey we have to detect it, too many bugs are caused by wrong configuration. |
PS: The both examples are not working. The first just failing with js Error, but the second is failing to preserve the state. |
@theKashey What JS error? First example works just fine for me. The issue I have is that I don't know what the component is going to be, so I need to put it inside a function. I can't export default it directly as it might be wrapped by another component. I was hoping that I could do something such as:
which would make it hot on the fly. That does not work though. To be more clear: This works:
This does not work:
What specifically makes |
Maybe I should rephrase my question..how would I correctly place a component inside another component for hot reload, but I don't know what the inner component is going to be? The below code does not hot reload, but is a basic idea of what I am trying to achieve. I don't know what component is going to be rendered until run-time.
|
You saw The only correct way to use import React from 'react'
import { hot } from 'react-hot-loader'
export default hot(module)(function App(Component) {
const Layout = () => <div>{Component}</div>
return Layout
}) it should be applied diffectly to the export. import React from 'react'
import { hot } from 'react-hot-loader'
import createLayout from './createLayout'
const Something = createLayout(SomeAnotherComponent);
export default hot(module)(function App {
return <Something />
} |
Idea - detect the module execution start and the module execution end. During this event HotExportedComponent could be mounted and rendered, but shall not be unmounted. If this event will occur - thus means that react-dom's render method was called, and that is misconfiguration case we are trying to solve. Fixes #765
@chrisabrams thanks for reporting, we added a warning that should help detecting wrong usage. I close this issue, feel free to ping us or to reopen a new one if you still have some problems using React Hot Loader. |
Thanks @neoziro, @theKashey I tried to follow the example provided but I cannot get the hot module function exported to return a component function/class. React continues to complain that it is returning an object :O I have created a sample repo with three files outlining what I am trying to do: https://github.com/chrisabrams/sandbox-hot-reload The |
I tried placing a console.log inside the function that is passed into |
When I check the typeof |
The challenge for me is that |
To sum up my comments: Why does this error with
But this works?
|
Cos you can not wrap with |
In you case you can wrap mport React from 'react'
import ReactDOM from 'react-dom'
import {AppContainer} from 'react-hot-loader'
import renderHot from './renderHot'
import Theme from './theme'
function render(){
const Component = new renderHot(<Theme />)
console.log('type theme', typeof Theme)
console.log('type hot', typeof Component) // Why am I type object when a function should be returned?
// Wrap everything with AppContainer
ReactDOM.render(<AppContainer><Component /></AppContainer>, document.getElementById('root'))
}
render();
if(module.hot) {
// accept the changes from that modules and re-render the app
module.hot.accept('./renderHot', render);
module.hot.accept('./theme', render);
} Dont forget to set modules:false in babel.rc This is actually the way v3(current) version work, explained as |
I followed your first example exactly so I'm not sure why you are saying I can't do that anymore. I just want to pass a component inside the function, and have that function return a component which is hot. I don't think that the v3/advanced way will work because I don't know what component I'll be wrapping, aka, I can't supply that component path in the |
The last example will work, as long it will work on application top-most level. There is nothing higher. export default hot(module)(function App(props) { <---- this is simple stateless functional component
return <Something />
}
export default hot(module)(function App(Component) { <-- this is not
return <Component />
} This is a way to make it work const makeItHot = hot(module); // get `the hot`, and mark module as hot
export default function renderHot(Component) {
const Wrapped = () => Component
return makeItHot(Wrapped) <-- apply `hot` here.
}) This will work, but will completely ignore different Components you may provide here – for any instance it always be "the last used". But better do as I said - dont wrap anything with
If you still don't clearly understand how it work - please invest some time into experiments. Try just to rethink the way you stuck with. |
Thanks. What I'm working on, I don't really know what the top most level component will be. I can create a wrapping component, but then that brings back to the issue you are describing where I would still need to wrap the second level component, which I won't know. I was able to get it working by wrapping the theme itself, that's good enough for now. Thanks for your help I'm sure I'll comment again when I come across a more advanced case. |
Any example of how to make it work with redux connect() ?
Only App.js and Index.js is hot-reloading rest doesnot. |
If you are reporting a bug or having an issue setting up React Hot Loader, please fill in below. For feature requests, feel free to remove this template entirely.
Description
For the
next
branch, the hot reload does not work if the component being rendered is started inside a function.Expected behavior
Being inside a function should not make any difference.
Actual behavior
It only works if the component being rendered is run at the top level. Meaning, the top level file that calls
ReactDOM.render
has to run directly,ReactDOM.render
cannot be run inside a function that mounts the component which has been "hotted."Environment
React Hot Loader version: next, ^4.0.0-beta.12
Run these commands in the project folder and fill in their results:
node -v
: v8.9.0npm -v
: 5.5.1Then, specify:
Reproducible Demo
Doesn't work
https://gist.github.com/chrisabrams/e0fe9cf8ea7347fe2364cc46cf378412
Does work
https://gist.github.com/chrisabrams/293a08cfb98b6d8f0bb5aff4464f5874
The text was updated successfully, but these errors were encountered: