-
Notifications
You must be signed in to change notification settings - Fork 47.2k
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
Bug: React.StrictMode breaks component that manage global object to break dependency between 2 related contexts #21930
Comments
We disable To work around, do let log = console.log and then use As for your problem, I haven't looked in detail (there is no reason to suspect a bug in React so you're better off asking on StackOverflow). But you're clearly breaking the rules of React. In React, rendering is supposed to be a pure function — you should not be modifying external objects or relying on order of different components rendering. So the approach you're using with modifying a global object during render is fundamentally flawed, and you need to rethink it. StrictMode surfaced it but since you're breaking the rules, there are likely other "normal" cases without StrictMode that are also broken. |
I would be able to give you a better answer if you made a sandbox with a much simplified version of your actual library code. No need for actual drawing of the arrow, but just enough to understand the data flow you wanted to have. |
after repetitive tests, I found out what exactly is the cause, and I still insist this is not expected, please read carefully: First I will use the next 2 terms
2 very important notes:
on StrictMode: codesee the next code (used in Xarrow.tsx), and lets remember react triggers 2 updates(at least) per render on StrictMode, if the first update will trigger another update(via setState for example) it will come before the second update strictmode schedules: if (shouldUpdatePosition.current) {
...
const pos = getPosition(...)
setSt(pos);
log('pos',pos)
shouldUpdatePosition.current = false;
}
log('st',st) on the first render recap, and logs:for logs explanation, let's say 0 is the wrong(not updated) value and 10 is the correct value
in order to fix this bug and make the result as expected react should take the value from the most recent update call and not the the first update call of the current cycle in strict mode code sandboxhttps://codesandbox.io/s/react-strict-mode-bug-bx8is?file=/src/index.js editmoved this to another issue #21956 |
I've just released v2.0 of a react-xarrows it breaks on apps that are wrapped with React.StrictMode. the component works perfectly fine on trees that are not wrapped with React.StrictMode
React version: 17.0.0
Steps To Reproduce
simple demo
code sandbox
ready to use dev enviroment
it takes about a minute to set up. this env will link react-xarrows to the running example on port 300, so any changes on ./src would immediately be reflected.
<ExamplePage />
with<React.StrictMode><ExamplePage /></React.StrictMode>
I've tested the lifecycle of react-xarrows in both mods and it appears to be identical, so I can't figure out why apps that use strictmode breaks react-xarrows. I could not figure out why react-xarrows is not printed in StrictMode,
related and possible cause
In simple words - I use a global object in the module Xwrapper.tsx, I pass a reference to this object to both contexts, then one context assigning 'update function'(a function that will cause xarrow to rerender) as a property and the second context consumes that function, and then elements connected to xarrow can selectively rerender only xarrow without triggering renders on other boxes.
I thought that maybe the fact that on StrictMode each render becomes 2 renders causing this issue, but it does not seem to be the problem.
The current behavior
react-xarrows does not work properly on react-trees wrapped with React.StrictMode
The expected behavior
the behavior should be identical in both cases.
The text was updated successfully, but these errors were encountered: