Comments (9)
A reduced repro of this change is
import { useState } from "react";
let stateId = 0;
export default function App() {
stateId++;
const [state] = useState(stateId);
return state;
}
What is happening here is that in React the App component is rendered twice. In 19 React preserves the state from the first render.
I think this is intentional by React preserving and re-using more state, but someone else might correct me.
from react.
This issue seems interesting! I would love to contribute or discuss further. ๐
from react.
This behavior is likely due to how React handles state and component updates in the given version. It seems like React is treating the useState call as if it is creating a new state object each time the component re-renders, which should not happen in a normal scenario. The behavior can be linked to potential issues or changes in state handling, particularly in versions around [email protected] as mentioned in the screenshotใ
Solution and Recommendation:
Ensure Stable useState Behavior: Make sure that useState is only called once for the same component instance, without causing unnecessary state recreation. This can be achieved by ensuring that the initialization logic is stable and not tied to re-renders.
Verify React Version and Known Issues:
Check the React version you are using and look for related issues in the React repository. The issue link (#29634) mentioned in the screenshot might provide more context.
Consider upgrading or downgrading React to see if this behavior changes, as it could be a bug or regression in a particular version.
Alternative State Management: If this behavior is confirmed as a bug or unintended side effect, consider using a different state management approach, such as useRef or useReducer, to maintain stable references and avoid unexpected destruction of state objects.
Modified Code Example (If Needed):
To illustrate a more stable approach using useRef instead of useState for maintaining object references:
import { useEffect, useRef } from "react";
let stateId = 0;
export default function App() {
const stateRef = useRef({
stateId: console.log(++stateId, "created") || stateId,
destroy() {
console.log(state ${this.stateId} destroyed
);
},
});
useEffect(() => {
return () => {
stateRef.current.destroy();
};
}, []);
console.log("render state", stateRef.current);
return
}
Key Changes:
Replaced useState with useRef to maintain a stable reference to the state object.
This ensures that the destroy method is only called when the component is unmounted, avoiding unexpected destruction of the state object.
By understanding the root cause and applying the appropriate fix, the component can behave predictably across different React versions.
from react.
Is this issue still opened ?
from react.
Is this issue still opened ?
Yes, neither React 19.x nor 18.x has solved this issue
from react.
It seems there's an issue with how the useEffect cleanup function references the state in StrictMode. The current implementation logs the initial stateId during cleanup, which can lead to confusion since stateId increments with each render.
To fix this, consider using an updateState function that retains the destroy method while creating a new state with an incremented stateId. This ensures the cleanup function references the correct state:` import { useEffect, useState } from "react";
let stateId = 0;
export default function App() {
const [state, setState] = useState({
stateId: ++stateId,
destroy() {
console.log(state ${this.stateId} destroyed
);
},
});
useEffect(() => {
return () => {
state.destroy();
};
}, [state]);
const updateState = () => {
setState({
stateId: ++stateId,
destroy: state.destroy, // Retain the destroy function from the previous state
});
};
console.log("render state", state);
return (
Update State
);
}
`
from react.
A more practical example
//In this example, it is a websocket connection, which can also be any object that is not suitable for creating in each rendering and should be destroyed when not use
class Connection {
constructor() {
// create ws connection
}
destroy() {
// close ws connection
}
}
function initState() {
return new Connection();
}
export default function App() {
const [connection, setConnection] = useState(initState);
useEffect(() => {
return () => {
connection.destroy();
};
}, [state]);
const reconnect = () => setConnection(initState())
return null;
}
Of course, we can easily solve this problem through the following way:
// init connection in useEffect
export default function App() {
const [connection, setConnection] = useState();
useEffect(() => {
const newConnection = initState();
setConnection(newConnection)
return () => {
newConnection.destroy();
};
}, [state]);
// But the type of connection become `Connection | undefined`,
// This will add some additional check logic
useMemo(() => {
if (!connection) return null; // <-
return connection;
}, []);
return null;
}
from react.
This issue has been automatically marked as stale. If this issue is still affecting you, please leave any comment (for example, "bump"), and we'll keep it open. We are sorry that we haven't been able to prioritize it yet. If you have any new additional information, please include it with your comment!
from react.
Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please create a new issue with up-to-date information. Thank you!
from react.
Related Issues (20)
- [Compiler Bug]: React Compiler breaks SuperToken's react-native global fetch patch HOT 3
- Bug: Fix: Expose event.submitter in React Synthetic Form Events
- [DevTools Bug] Minified React error #310; visit https://react.dev/errors/310 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.
- Bug for facebook graph api (I know this might not relate the topic but please show it That someone from meta helps us) HOT 1
- Bug: Detached nodes are created when portal is rendered conditionally
- [Compiler]: Detection for calling components as functions (instead of JSX) HOT 2
- Bug: CSS not being applied properly in Chrome with React experimental HOT 1
- [Compiler Bug]: Compiler errors when optimizing component with spread assignment in `if` in `while` loop HOT 1
- Bug: Conditional button rendering with button and submit inside a form causes type="button" to submit HOT 2
- [Compiler Bug]: compiler doesn't work with `@svgr/webpack` HOT 1
- [Compiler]: Detect use of callback refs for layout synchronization HOT 1
- [Compiler]: passing `ref` to render prop will void optimization
- [Compiler]: flags mutations of shared mutable refs and skips optimizations
- [DevTools Bug]: Context display does not support HOC name tagging
- [Compiler]: Suppressing ref validation errors makes it unclear why code accessing refs is unmemoized HOT 1
- Bug:
- Bug:
- Bug:
- [DevTools Bug]: UI not using full window space HOT 3
- [Compiler Bug]: React fails to rerender list items when using compiler with zustand store HOT 1
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.