React App内存泄漏和取消所有订阅报错如何解决?
How to Resolve Memory Leak and Cancel All Subscriptions Error in React App?
我的 React 应用程序的控制台中有一个警告,其中提到内存泄漏和说明。我不确定如何重构我的代码以合并componentWillUnmount。
我做有 useEffect() 和 JS 承诺代码从 Firebase 数据库中提取和呈现数据,但错误没有提到该组件。
请阅读下面的完整警告错误:
Warning: Can't perform a React state update on an unmounted component.
This is a no-op, but it indicates a memory leak in your application.
To fix, cancel all subscriptions and asynchronous tasks in the
componentWillUnmount method.
in Nav (at Home.js:32)
in div (at Home.js:30)
in DashHome (created by Context.Consumer)
Nav.js代码:
class Nav extends Component {
state = {
isSignedIn: true
}
componentDidMount = () => {
firebase.auth().onAuthStateChanged(user => {
this.setState({ isSignedIn: user })
})
}
render() {
return (
<div className="side-nav">
<Nav vertical>
<NavItem>
<NavLink href="#">Home</NavLink>
</NavItem>
{this.state.isSignedIn ? (
<div>
<Button onClick={() => firebase.auth().signOut()}>Sign-out</Button>
</div>
) : (
<Redirect to="/" />
)}
</Nav>
</div>
);
}
}
export default Nav;
Home.js 组件(一些代码)
export default function Home() {
const generateData = (value, length = 5) =>
d3.range(length).map((item, index) => ({
date: index,
value: value === null || value === undefined ? Math.random() * 100 : value
}));
const [data, setData] = useState(generateData(0));
const changeData = () => {
setData(generateData());
};
useEffect(
() => {
setData(generateData());
},
[!data]
);
我在教程中阅读了有关 AbortController API 的内容,但我没有在我的应用程序中使用 Fetch。
感谢您的观看!请随意 post 任何代码重构想法来解决这个问题。
勾选所有更新组件状态的函数。当您更新未在 state = {} 中定义的状态时,通常会发生该错误。
例如;
将组件安装为
时的初始状态
state = {
isSignedIn: true,
};
然后在您的代码中的某处,您更新了一个没有预定义引用的状态,
this.setState({ someOtherRefs: certainValue });
React 会报错,因为 someOtherRefs 在挂载组件时没有定义。
大家试试看你在状态更新函数中是否使用了正确的拼写。
函数returns调用时取消订阅。
var unsubscribe = firebase.auth().onAuthStateChanged(function (user) {
// handle it
});
你应该像这样在 componentWillUnmount 中调用这个函数。
let unsubscribe;
class Nav extends Component {
state = {
isSignedIn: true
}
componentDidMount = () => {
unsubscribe = firebase.auth().onAuthStateChanged(user => {
this.setState({
isSignedIn: user
})
})
}
componentWillUnmount() {
unsubscribe()
}
我的 React 应用程序的控制台中有一个警告,其中提到内存泄漏和说明。我不确定如何重构我的代码以合并componentWillUnmount。
我做有 useEffect() 和 JS 承诺代码从 Firebase 数据库中提取和呈现数据,但错误没有提到该组件。
请阅读下面的完整警告错误:
Warning: Can't perform a React state update on an unmounted component.
This is a no-op, but it indicates a memory leak in your application.
To fix, cancel all subscriptions and asynchronous tasks in the
componentWillUnmount method.
in Nav (at Home.js:32)
in div (at Home.js:30)
in DashHome (created by Context.Consumer)
Nav.js代码:
class Nav extends Component {
state = {
isSignedIn: true
}
componentDidMount = () => {
firebase.auth().onAuthStateChanged(user => {
this.setState({ isSignedIn: user })
})
}
render() {
return (
<div className="side-nav">
<Nav vertical>
<NavItem>
<NavLink href="#">Home</NavLink>
</NavItem>
{this.state.isSignedIn ? (
<div>
<Button onClick={() => firebase.auth().signOut()}>Sign-out</Button>
</div>
) : (
<Redirect to="/" />
)}
</Nav>
</div>
);
}
}
export default Nav;
Home.js 组件(一些代码)
export default function Home() {
const generateData = (value, length = 5) =>
d3.range(length).map((item, index) => ({
date: index,
value: value === null || value === undefined ? Math.random() * 100 : value
}));
const [data, setData] = useState(generateData(0));
const changeData = () => {
setData(generateData());
};
useEffect(
() => {
setData(generateData());
},
[!data]
);
我在教程中阅读了有关 AbortController API 的内容,但我没有在我的应用程序中使用 Fetch。
感谢您的观看!请随意 post 任何代码重构想法来解决这个问题。
勾选所有更新组件状态的函数。当您更新未在 state = {} 中定义的状态时,通常会发生该错误。 例如; 将组件安装为
时的初始状态 state = {
isSignedIn: true,
};
然后在您的代码中的某处,您更新了一个没有预定义引用的状态,
this.setState({ someOtherRefs: certainValue });
React 会报错,因为 someOtherRefs 在挂载组件时没有定义。
大家试试看你在状态更新函数中是否使用了正确的拼写。
函数returns调用时取消订阅。
var unsubscribe = firebase.auth().onAuthStateChanged(function (user) {
// handle it
});
你应该像这样在 componentWillUnmount 中调用这个函数。
let unsubscribe;
class Nav extends Component {
state = {
isSignedIn: true
}
componentDidMount = () => {
unsubscribe = firebase.auth().onAuthStateChanged(user => {
this.setState({
isSignedIn: user
})
})
}
componentWillUnmount() {
unsubscribe()
}