Meteor.logout() 在 React 中导致内存泄漏
Meteor.logout() causing memory leak in React
当我注销我的 meteor 应用程序时,出现内存泄漏错误。它似乎有大约 50% 的时间发生,我不知道我在这里做错了什么。谁能解释一下我的方法有什么问题。
错误信息
无法对未安装的组件执行 React 状态更新。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要修复,取消 componentWillUnmount 方法中的所有订阅和异步任务。
应用详情
Metoer、React、React-Router V4
路径:LogoutButton.jsx
class LogoutButton extends React.Component {
constructor(props) {
super(props);
this.state = {
logoutRedirect: false
};
this.handleLogout = this.handleLogout.bind(this);
}
handleLogout = e => {
e.preventDefault();
Meteor.logout(err => {
if (err) {
console.log('err', err);
} else {
this.setState({ logoutRedirect: true });
}
});
};
render() {
const logoutRedirect = this.state;
if (logoutRedirect.logoutRedirect) {
return <Redirect to="/" />;
}
return (
<button
type="button"
className="btn btn-link dropdown-item text-dark"
onClick={this.handleLogout}
>
<FontAwesomeIcon icon={faSignOutAlt} className="mr-2 text-dark" />
Logout
</button>
);
}
}
如果有人能对此提供更多说明,我将不胜感激。问题似乎出在我处理经过身份验证的路由的方式上。我已经用下面的代码解决了这个错误,但是,我不太确定为什么会这样,所以我无法给出解释。解决方案是更改操作顺序。首先,更新状态以重定向路由,然后注销用户。
class LogoutButton extends React.Component {
constructor(props) {
super(props);
this.state = {
logoutRedirect: false
};
this.handleLogout = this.handleLogout.bind(this);
}
componentWillUnmount() {
document.removeEventListener('click', this.handleLogout);
}
handleLogout = e => {
e.preventDefault();
this.setState({ logoutRedirect: true });
Meteor.logout(err => {
if (err) {
console.log('err', err);
}
});
};
render() {
const logoutRedirect = this.state;
if (logoutRedirect.logoutRedirect) {
return <Redirect to="/" />;
}
return (
<button
type="button"
className="btn btn-link dropdown-item text-dark"
onClick={this.handleLogout}
>
<FontAwesomeIcon icon={faSignOutAlt} className="mr-2 text-dark" />
Logout
</button>
);
}
}
step1.流星
文件夹添加这个包:
账户-ui
账户-google
帐户密码
账户基础
std:accounts-ui
useraccounts:bootstrap
//
第2步 :
文件夹:imports/startup
创建文件夹名称 "accounts" 添加帐户-config.js 并粘贴代码。
将 FlowRouter.go('/account/sign-in') 更改为
第 3 步:为您的按钮添加功能。粘贴此
let handleLogout = () => {
AccountsTemplates.logout()
}
const LogoutButton = () => {
let handleLogout = event => {
event.preventDefault()
AccountsTemplates.logout()
}
return (
<button
type="button"
className="btn btn-link dropdown-item text-dark"
onClick={handleLogout}
>
<FontAwesomeIcon icon={faSignOutAlt} className="mr-2 text-dark" />
Logout
</button>
)
}
注意:我使用的是帐户基础。
// Configure Accounts Templates default
AccountsTemplates.configure({
enablePasswordChange: true,
sendVerificationEmail: true,
enforceEmailVerification: true,
showForgotPasswordLink: true,
negativeValidation: true,
positiveValidation: true,
negativeFeedback: true,
positiveFeedback: true,
// Proceed to main page as you log out..
onLogoutHook: () => {
<Redirect to="/" />
}
})
所以我会为您分解一下,以了解错误是什么,您为什么 运行 陷入其中以及一些可能的解决方案。
您的组件 LogoutButton
运行 处于卸载(完全未呈现)但试图触发组件内状态更改的场景中。这通常只是糟糕的状态流,通常源于执行一些需要时间执行的异步操作,然后在没有任何东西可以触发 setState 时触发 setState。
看看你的代码,听起来你想做的是这样的:
- 你有一个
<LogoutButton />
渲染到屏幕上,当
用户点击它,他们应该被重定向。
- 当用户单击该按钮时,它会触发
handleLogout
,它会显式调用 Meteor.logout
(我假设这是正式将用户从会话中注销的原因),然后继续调用 setState
.
很可能,Meteor.logout
在这里有一些副作用,因此您的 LogoutButton
不再安装或渲染。当您的组件到达需要调用 setState
的步骤时,您的组件已卸载(可能某些父组件已决定不再显示它,等等)。
我对 React-Router 了解不够(这是我假设 <Redirect />
来自但它看起来像 history.push
或将一个名为 push
的道具传递给 <Redirect />
是值得考虑的东西。参见 this article。
当我注销我的 meteor 应用程序时,出现内存泄漏错误。它似乎有大约 50% 的时间发生,我不知道我在这里做错了什么。谁能解释一下我的方法有什么问题。
错误信息
无法对未安装的组件执行 React 状态更新。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要修复,取消 componentWillUnmount 方法中的所有订阅和异步任务。
应用详情
Metoer、React、React-Router V4
路径:LogoutButton.jsx
class LogoutButton extends React.Component {
constructor(props) {
super(props);
this.state = {
logoutRedirect: false
};
this.handleLogout = this.handleLogout.bind(this);
}
handleLogout = e => {
e.preventDefault();
Meteor.logout(err => {
if (err) {
console.log('err', err);
} else {
this.setState({ logoutRedirect: true });
}
});
};
render() {
const logoutRedirect = this.state;
if (logoutRedirect.logoutRedirect) {
return <Redirect to="/" />;
}
return (
<button
type="button"
className="btn btn-link dropdown-item text-dark"
onClick={this.handleLogout}
>
<FontAwesomeIcon icon={faSignOutAlt} className="mr-2 text-dark" />
Logout
</button>
);
}
}
如果有人能对此提供更多说明,我将不胜感激。问题似乎出在我处理经过身份验证的路由的方式上。我已经用下面的代码解决了这个错误,但是,我不太确定为什么会这样,所以我无法给出解释。解决方案是更改操作顺序。首先,更新状态以重定向路由,然后注销用户。
class LogoutButton extends React.Component {
constructor(props) {
super(props);
this.state = {
logoutRedirect: false
};
this.handleLogout = this.handleLogout.bind(this);
}
componentWillUnmount() {
document.removeEventListener('click', this.handleLogout);
}
handleLogout = e => {
e.preventDefault();
this.setState({ logoutRedirect: true });
Meteor.logout(err => {
if (err) {
console.log('err', err);
}
});
};
render() {
const logoutRedirect = this.state;
if (logoutRedirect.logoutRedirect) {
return <Redirect to="/" />;
}
return (
<button
type="button"
className="btn btn-link dropdown-item text-dark"
onClick={this.handleLogout}
>
<FontAwesomeIcon icon={faSignOutAlt} className="mr-2 text-dark" />
Logout
</button>
);
}
}
step1.流星
文件夹添加这个包:
账户-ui
账户-google
帐户密码
账户基础
std:accounts-ui
useraccounts:bootstrap
//
第2步 :
文件夹:imports/startup
创建文件夹名称 "accounts" 添加帐户-config.js 并粘贴代码。
将 FlowRouter.go('/account/sign-in') 更改为
第 3 步:为您的按钮添加功能。粘贴此
let handleLogout = () => {
AccountsTemplates.logout()
}
const LogoutButton = () => {
let handleLogout = event => {
event.preventDefault()
AccountsTemplates.logout()
}
return (
<button
type="button"
className="btn btn-link dropdown-item text-dark"
onClick={handleLogout}
>
<FontAwesomeIcon icon={faSignOutAlt} className="mr-2 text-dark" />
Logout
</button>
)
}
注意:我使用的是帐户基础。
// Configure Accounts Templates default
AccountsTemplates.configure({
enablePasswordChange: true,
sendVerificationEmail: true,
enforceEmailVerification: true,
showForgotPasswordLink: true,
negativeValidation: true,
positiveValidation: true,
negativeFeedback: true,
positiveFeedback: true,
// Proceed to main page as you log out..
onLogoutHook: () => {
<Redirect to="/" />
}
})
所以我会为您分解一下,以了解错误是什么,您为什么 运行 陷入其中以及一些可能的解决方案。
您的组件 LogoutButton
运行 处于卸载(完全未呈现)但试图触发组件内状态更改的场景中。这通常只是糟糕的状态流,通常源于执行一些需要时间执行的异步操作,然后在没有任何东西可以触发 setState 时触发 setState。
看看你的代码,听起来你想做的是这样的:
- 你有一个
<LogoutButton />
渲染到屏幕上,当 用户点击它,他们应该被重定向。 - 当用户单击该按钮时,它会触发
handleLogout
,它会显式调用Meteor.logout
(我假设这是正式将用户从会话中注销的原因),然后继续调用setState
.
很可能,Meteor.logout
在这里有一些副作用,因此您的 LogoutButton
不再安装或渲染。当您的组件到达需要调用 setState
的步骤时,您的组件已卸载(可能某些父组件已决定不再显示它,等等)。
我对 React-Router 了解不够(这是我假设 <Redirect />
来自但它看起来像 history.push
或将一个名为 push
的道具传递给 <Redirect />
是值得考虑的东西。参见 this article。