Comments (2)
The issue you're experiencing is due to the way React handles updates and re-renders. When your component first renders, ref.current
is initialized to 0. However, in the same render cycle, you're incrementing ref.current
inside a useEffect hook without any dependencies. This means that the effect will run after every render, including the initial one. So, on the first render, ref.current
is incremented from 0 to 1, then on the second render it's incremented again from 1 to 2, and so on. That's why you're seeing 2, 3, 4, etc., instead of 1, 2, 3, etc.
To fix this, you need to ensure that ref.current
is only incremented once per render cycle. One way to do this is to use a separate state variable to track whether it's the first render or not. Here's how you can modify your code:
First Method is using useState
hook:
//previous code
const [isFirstRender, setIsFirstRender] = useState(true);
const ref = useRef(0);
useEffect(() => {
if (isFirstRender) {
setIsFirstRender(false);
} else {
ref.current = ref.current + 1;
}
});
//previous code
Second method is using useRef
hook:
//previous code
const log = useRef(true)
const ref = useRef(0);
useEffect(() => {
if (log.current) {
log.current = false
} else {
ref.current = ref.current + 1;
}
});
//previous code
from react.
@AliHaiderPgm thats a good thought, but the effect doesn't run until after render so it will show 0,1,2,3,4 as expected as written outside of strict mode. Your fix does solve the issue, because it skips the count for the first strict mode effect, but if this was run in prod it would miss the first render, since strict mode doesn't run in prod.
The issue is that React 18 introduced a new feature for StrictMode that immediately unmounts and remounts effects to ensure they're properly cleaned up, to catch bugs like this. That's why it worked before 18 and doesn't work as expected.
Check out this sandbox, and notice that is works if you remove from index.js: https://codesandbox.io/p/sandbox/blissful-darkness-xyz6m6?file=%2Fsrc%2Findex.js%3A10%2C18
The reason this is a bug is because when the component unmounts, you're not resetting the ref. That means when you use certain features, the ref won't be reset when you expect it to. For example, when Fast Refresh updates the component, you would expect the render count to reset to 0, but in your version the render count gets "stuck" at the current value and you need to hard refresh the page to reset it to 0.
In future versions we plan to reset refs for you in strict mode to align with the production behavior (#25049), but hopefully this shows the value of the new strict mode behavior.
Until that lands, to fix this, you can reset the ref when the component unmounts. You need two effects to do this because the effect that updates the count will destroy on every render, but you only want to reset on unmount:
const ref = useRef(0);
useEffect(() => {
ref.current = ref.current + 1;
});
useEffect(() => {
return () => {
ref.current = 0;
};
}, []);
Note: we also have a planned feature to support doing this in a single effect by allowing you to specify different functions that run for create vs update in the same effect: #25744
from react.
Related Issues (20)
- [DevTools Bug] Children cannot be added or removed during a reorder operation.
- Bug: SetState with same value, rerenders one more time HOT 2
- [DevTools Bug]: TypeError: ie.handlePostCommitFiberRoot is not a function HOT 3
- Hey really.org
- Bug: Invalid options to hydrateRoot can error with "This root received an early update"
- Bug: `Children.map` raises error when passed async server component within client component HOT 3
- Bug: mouse events are bubbled up too far with some pointer-events rules HOT 1
- Bug: Unsupported HTML character references HOT 6
- Bug: React not defined in TypeScript when importing from npm HOT 8
- After using forwardRef in a JSX component, you encounter an error when using it in a TSX component. HOT 1
- [DevTools Bug] Could not find node with id "464" in commit tree HOT 1
- ⚠Phishing Website Warning!!! There are phishing website links in the document. HOT 6
- not showing components in inspect its stuck
- [DevTools Bug]: I can't see the "Profiler" and "Components" in my dev tools HOT 1
- [DevTools Bug]: I can't see the "Profiler" and "Components" in my dev tools HOT 2
- Bug: Event handling with portals is broken
- Feature Request: useOnLoadEffect() -> empty dependency array useEffect wrapper
- Larger files upload rejection message instead of net::ERR_CONNECTION_RESET
- Bug: yo HOT 1
- Bug: refObj returned from useRef is not sealed
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from react.