Repository: react
Issue: react-refresh: Dependent functions/data don't trigger refresh
Labels: Type: Discussion

**Do you want to request a *feature* or report a *bug*?**

Both/neither?

**What is the current behavior?**

Currently, react-refresh marks each component whose `type` and/or `signature` has changed as "dirty" and will either re-render or re-mount those components selectively.

The problem occurs when the dev tooling (webpack, parcel, etc.) loads a module that exports functions or data that are used inside of components, but aren't registered components themselves. For example, a utility function that concatenates a string:

```js
export greet(name) {
  return `Hello, ${name}!`;
}
```

Changing the returned string to `Yo, ${name}!` would trigger this module to reload in the browser, but because components which depended on it don't reload, the old greeting will persist 
until the next render of each dependent component.

(BTW in actuality, some tooling will reload immediate dependents of modules that are reloaded in order to get around similar problems. You can extend the dependency chain from two to three modules, where `a.js` depends on `b.js` depends on `c.js`, and you will get the same result when editing `c.js`)

What this forces tooling to do is apply a heuristic to try and guess whether a given module should be refreshed, vs. completely restart the app in order to cause all components to re-mount and pick up any changes that wouldn't be picked up by react-refresh.

The problems with the heuristic approach is:
- each dev tool needs to implement this logic, leading to more potential for bugs
- it leads to a degradation of hot reloading capabilities based on what your module exports. not obvious at all on it's face and will lead people to twisting their code base to route around this
- It's very unfriendly to compile-to-JS languages like ReasonML, ClojureScript, etc. which might have different default semantics for what is public / private, different conventions for naming components, etc. which make it difficult to detect whether a module is "safe" to refresh

**What is the expected behavior?**

That components depended on newly loaded code will pick up those changes correctly, without losing state.

A potential (maybe naive?) solution to this in react-refresh is, instead of only re-rendering the components marked as dirty (due to a different `type` being registered), to _re-render from the root_ while maintaining hooks state. If components' signatures have changed, then re-mount.

I've read through and kind of grok most of the code in react-refresh, but I'm not sure how this would impact the way that the reconciler currently handles the HMR stuff. This is as much of a question, as it is a request: could this be a viable solution?

I appreciate your time and energy in reading through this. I'm very excited about having first-class support for hot reloading in React, as it's been something that I've loved ever since seeing the first demo of it. I hope that this issue can help create a way to provide a consistently excellent dev experience across tools/platforms/languages!

**Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?**

React 16.11