Reactjs 对未安装的组件进行反应状态更新。这是一个no-op,但它表示应用程序中存在内存泄漏

Reactjs 对未安装的组件进行反应状态更新。这是一个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

我在练习AWS的Cognito。对于前端,我使用React,对于路由,我使用React路由器dom。对于Cognito验证,我使用包。我的Congito
登录
注册
确认
逻辑工作正常。我制作了一个助手函数,用于验证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次?)看到这个错误,但我认为这与这个问题无关。现在重新加载页面似乎可以解决这个问题。请注意,现在在控制台中,您不再收到关于尝试更新未安装组件状态的警告。