Reactjs 对未安装的组件进行反应状态更新。这是一个no-op,但它表示应用程序中存在内存泄漏
我在练习AWS的Cognito。对于前端,我使用React,对于路由,我使用React路由器dom。对于Cognito验证,我使用包。我的CongitoReactjs 对未安装的组件进行反应状态更新。这是一个no-op,但它表示应用程序中存在内存泄漏,reactjs,callback,react-hooks,amazon-cognito,use-effect,Reactjs,Callback,React Hooks,Amazon Cognito,Use Effect,我在练习AWS的Cognito。对于前端,我使用React,对于路由,我使用React路由器dom。对于Cognito验证,我使用包。我的Congito登录,注册和确认逻辑工作正常。我制作了一个助手函数,用于验证Congnito。并在不同的组件中重用它。我把导航条分成两部分。从Congnito到当前用户,我创建了一个回调函数,并在useEffect中使用它,并且依赖项将回调函数放入,默认情况下getAuthenticatedUser为null。我添加了获取数据的条件,如果getAuthentic
登录
,注册
和确认
逻辑工作正常。我制作了一个助手函数,用于验证Congnito。并在不同的组件中重用它。我把导航条分成两部分。从Congnito到当前用户,我创建了一个回调函数,并在useEffect中使用它,并且依赖项将回调函数放入,默认情况下getAuthenticatedUser
为null。我添加了获取数据的条件,如果getAuthenticatedUser
,则重定向到signin
和signup
页面。由于这种情况,我收到错误:无法对未安装的组件执行React状态更新…
。此外,当我登录时,它不会更改导航栏名称,我必须刷新浏览器,然后才能看到更改。我在中共享我的代码
这是我的助手功能
import React, { useState, useCallback, useEffect, useMemo } from 'react';
import { CognitoUserPool } from 'amazon-cognito-identity-js';
const Pool_Data = {
UserPoolId: 'us-east-1_IEyFfUupx',
ClientId: '63fc9g5c3g9vhqdalrv9eqhoa2',
};
export default function useHandler() {
const [state, setstate] = useState({
loading: false,
isAuthenticated: false
})
const { loading, isAuthenticated } = state;
const userPool = new CognitoUserPool(Pool_Data)
const getAuthenticatedUser = useCallback(() => {
return userPool.getCurrentUser();
},
[],
);
console.log(getAuthenticatedUser());
useEffect(() => {
getAuthenticatedUser()
}, [getAuthenticatedUser])
const signOut = () => {
return userPool.getCurrentUser()?.signOut()
}
console.log(getAuthenticatedUser());
return {
loading,
isAuthenticated,
userPool,
getAuthenticatedUser,
signOut
}
};
import React, { useEffect } from "react";
import { Link } from "react-router-dom";
import SigninLinks from './SigninLinks';
import SignoutLinks from './SignoutLinks';
import useHandlder from '../configHandler/useHandler';
const Nav = () => {
const { getAuthenticatedUser } = useHandlder();
const Links = getAuthenticatedUser() ? <SigninLinks /> : <SignoutLinks />
return (
<nav className="nav-wrapper grey darken-3">
<div className="container">
<h2 className="brand-logo">Logo</h2>
{
Links
}
</div>
</nav>
);
};
export default Nav;
这是我的导航
import React, { useState, useCallback, useEffect, useMemo } from 'react';
import { CognitoUserPool } from 'amazon-cognito-identity-js';
const Pool_Data = {
UserPoolId: 'us-east-1_IEyFfUupx',
ClientId: '63fc9g5c3g9vhqdalrv9eqhoa2',
};
export default function useHandler() {
const [state, setstate] = useState({
loading: false,
isAuthenticated: false
})
const { loading, isAuthenticated } = state;
const userPool = new CognitoUserPool(Pool_Data)
const getAuthenticatedUser = useCallback(() => {
return userPool.getCurrentUser();
},
[],
);
console.log(getAuthenticatedUser());
useEffect(() => {
getAuthenticatedUser()
}, [getAuthenticatedUser])
const signOut = () => {
return userPool.getCurrentUser()?.signOut()
}
console.log(getAuthenticatedUser());
return {
loading,
isAuthenticated,
userPool,
getAuthenticatedUser,
signOut
}
};
import React, { useEffect } from "react";
import { Link } from "react-router-dom";
import SigninLinks from './SigninLinks';
import SignoutLinks from './SignoutLinks';
import useHandlder from '../configHandler/useHandler';
const Nav = () => {
const { getAuthenticatedUser } = useHandlder();
const Links = getAuthenticatedUser() ? <SigninLinks /> : <SignoutLinks />
return (
<nav className="nav-wrapper grey darken-3">
<div className="container">
<h2 className="brand-logo">Logo</h2>
{
Links
}
</div>
</nav>
);
};
export default Nav;
import React,{useffect}来自“React”;
从“react router dom”导入{Link};
从“/SigninLinks”导入SigninLinks;
从“/SignoutLinks”导入SignoutLinks;
从“../configHandler/useHandler”导入useHandler;
常量导航=()=>{
const{getAuthenticatedUser}=usehandler();
const Links=getAuthenticatedUser()?:
返回(
标志
{
链接
}
);
};
导出默认导航;
这是主屏幕,显示数据和获取错误
import React, { useState, useEffect } from "react";
import { api } from './api';
import useHandlder from './configHandler/useHandler'
import { Redirect } from 'react-router-dom';
const Home = () => {
const [state, setstate] = useState([]);
const { getAuthenticatedUser } = useHandlder();
useEffect(() => {
fetchData()
}, [])
const fetchData = async () => {
const response = await fetch(`https://jsonplaceholder.typicode.com/posts`);
const data = await response.json();
setstate(data)
}
return getAuthenticatedUser() === null ? <Redirect to="/signin" /> : //In here is the //error happening.
<div className="row">
<h1>hello welcome to home</h1>
{
state?.map((i: string, id: number) => <h1 key={id}>{i.title}</h1>)
}
</div>
};
export default Home;
import React,{useState,useffect}来自“React”;
从“/api”导入{api};
从“./configHandler/useHandler”导入useHandler
从'react router dom'导入{Redirect};
常量Home=()=>{
const[state,setstate]=useState([]);
const{getAuthenticatedUser}=usehandler();
useffect(()=>{
fetchData()
}, [])
const fetchData=async()=>{
const response=等待获取(`https://jsonplaceholder.typicode.com/posts`);
const data=wait response.json();
设置状态(数据)
}
return getAuthenticatedUser()==null?://这里是//发生的错误。
你好,欢迎到家
{
state?.map((i:string,id:number)=>{i.title})
}
};
导出默认主页;
问题
问题是,您的应用程序在主路径(“/”
)上启动,并呈现主组件Home
在装载时启动GET请求并检查经过身份验证的用户,如果没有,则重定向到您的“/signin”路由
fetch
是异步的,因此当发生重定向时,GET请求将在Home
卸载后解析,并尝试用响应数据更新本地状态,但无法执行
解决方案
您需要使用取消飞行中的请求。如果组件卸载,效果清理函数将取消提取请求。在Home
中,更新useffect
钩子以创建一个AbortController
和signal
以用于清除功能
useEffect(() => {
const controller = new AbortController(); // <-- create controller
const { signal } = controller; // <-- get signal for request
const fetchData = async () => {
const response = await fetch(
`https://jsonplaceholder.typicode.com/posts`,
{ signal } // <-- pass signal with options
);
const data = await response.json();
setstate(data);
};
fetchData();
return () => controller.abort(); // <-- return cleanup function to abort
}, []);
useffect(()=>{
const controller=new AbortController();//这是否回答了您的问题?在您的情况下,您从主路径开始(“/”
)当Home
挂载时进行提取,但是重定向
推送一个新路由并Home
unmounts.Hmmm。对于我的代码,我应该怎么做?按照我的解决方案,实际上回调创建一个中止控制器和信号,与fetch
GET请求一起发送,并向abo返回一个清除函数如果Home
提前卸载,请不要做出任何未解决的承诺。如果另一个答案不太清楚,我可以在这里回答,如果你愿意的话。我没有得到答案,我创建了用户名:test12和密码:Helloworld1!。我现在遇到了这个错误:index.js:1未捕获错误:你提供的错误不包含堆栈跟踪。
@krisna我添加了指向运行我测试过的codesandbox。我偶尔也会(5次中有1次?)看到这个错误,但我认为这与这个问题无关。现在重新加载页面似乎可以解决这个问题。请注意,现在在控制台中,您不再收到关于尝试更新未安装组件状态的警告。