Reactjs Can';t在未安装的组件上执行React状态更新。React、redux和useEffect存在问题

Reactjs Can';t在未安装的组件上执行React状态更新。React、redux和useEffect存在问题,reactjs,redux,react-redux,axios,react-hooks,Reactjs,Redux,React Redux,Axios,React Hooks,我有一个使用如下钩子的React组件: const myComponent = (props) => { useEffect(() => { FetchData() .then(data => { setState({data: data}); } // some other code }, []); //some other code and render method... } fetchData负责使用axi

我有一个使用如下钩子的React组件:

const myComponent = (props) => {
  useEffect(() => {
     FetchData()
     .then(data => {
       setState({data: data});
     }
    // some other code
  }, []);

//some other code and render method...
}
fetchData负责使用axios并从API获取数据:

const FetchData = async () => {
   try {
    res = await myApiClient.get('/myEndpoint);
   } catch (err) {
    console.log('error in FetchData');
    res = err.response
}
}
最后,myApiClient是外部定义的。为了能够使用不同的API,我不得不使用这个设置

import axios from "axios";
axios.defaults.headers.post["Content-Type"] = "application/json";

const myApiClient = axios.create({
  baseURL: process.env.REACT_APP_API1_BASEURL
});
const anotherApiClient = axios.create({
  baseURL: process.env.REACT_APP_API2_BASEURL
});

export {
  myApiClient,
  anotherApiClient
};
通过这种设置,我得到了警告

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 a useEffect cleanup function.
我在谷歌上搜索了一下,看到了一些关于如何清理useEffect请求的建议,比如,但我的axios是外部定义的。那么,如何使用此设置发送取消

此外,应用程序正在使用redux,不确定是否以某种方式涉及到它


欢迎任何其他避免错误的建议。

您可以使用
rxjs
中的
defer
来实现以下目的:

const FetchData = () => {
  try {
    return myApiClient.get("/myEndpoint");
  } catch (err) {
    console.log("error in FetchData");
    return err.response;
  }
};

const myComponent = (props) => {
  useEffect(() => {
    const subscription = defer(FetchData()).subscribe({
      next: ({
        data
      }) => {
        setState({
          data: data
        });
      },
      error: () => {
        // error handling
      },
      complete: () => {
        // cancel loading state etc
      }
    });

    return () => subscription.unsubscribe();
  }, []);
}

始终检查您是否正在处理fetch或任何长操作

let _isMounted = false;

const HooksFunction = props => {


  const [data, setData] = useState({}); // data supposed to be object

  const fetchData = async ()=> {
    const res = await myApiClient.get('/myEndpoint');
    if(_isMounted) setData(res.data); // res.data supposed to return an object
  }

  useEffect(()=> {

    _isMounted = true;

    return ()=> {
        _isMounted = false;
    }

  },[]);

  return (
    <div>
      {/*....*/}
    <div/>
  );

}
let _isMounted=false;
const HooksFunction=props=>{
const[data,setData]=useState({});//应该是对象的数据
const fetchData=async()=>{
const res=await myApiClient.get('/myEndpoint');
if(_isMounted)setData(res.data);//res.data应该返回一个对象
}
useffect(()=>{
_isMounted=真;
return()=>{
_isMounted=错误;
}
},[]);
返回(
{/*....*/}
);
}

你说的“外部”是什么意思?您可以传递到axios请求,并在必要时取消它。我的意思是,我不知道如何将MyApicClient中定义的cancellationToken一直传递到组件中的useEffect。我可以先导出它,然后再导入吗?问题是由Redux Store引起的。这里的解决方案:在项目中使用
rxjs
不是一个好主意,如果因为它的大小而没有在其他任何地方使用它,我想你可以单独导入
defer
,并利用树抖动来不包括整个库。如果我不够清楚,很抱歉。FetchData位于另一个文件中,并从组件中的useEffect导出以供使用。感谢不管是否导出,您只需检查
是否(\u isMounted)
然后更新状态。