Added failing tests for mutable source mutate during render #20199
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Reported in #19948.
This test case highlights that mutating a source while rendering a component that reads from the source causes mutable source to throw an error:
Mutating a mutable source (or any external variable) during render isn't supported and is expected not to work. The problem here is that the error message misattributes it as a React bug.
Should this be supported?
This seems very similar lazily initializing a ref so it might be tempting to think it's okay. Mutable sources are external though, so modifying them during render is a side effect which makes it unsafe and unsupported. So while we could "support" this case in a very limited way, we shouldn't.
Could we warn better?
Maybe there's a way we could detect this case and give a better error message though? Conceptually, checking the mutable source version an additional time before returning the result of the render would be sufficient to detect and warn about this. I think this would require us to track all of the mutable sources that are read during render and loop through them at the end of
renderWithHooks
to check one more time. This seems like something we would not want to do in production and throwing a different error in DEV seems weird. We could log an error and then throw but that also seems weird.Maybe an alternate approach would be to store the version number of the source somewhere (where we store other DEV-only metadata, maybe the source itself) the first time a Fiber reads it and then check the version if the Fiber renders again to make sure it's the same. I'll look into this.