在 axios 函数调用中设置状态,然后在 useEffect 钩子中调用函数

Setting state inside of axios function call, then call function in useEffect hook

提问人:user13919384 提问时间:7/4/2022 最后编辑:user13919384 更新时间:7/4/2022 访问量:72

问:

我正在使用 React 功能组件。 我在 axios 调用中设置状态,然后在 useEffect 钩子中调用该函数。

这是我的函数:


import { useDispatch } from “react-redux”;

functon ABCComponent({ navigation }){

    const dispatch = useDispatch();
   
    const testPostID = "1234567891011";
    
    const [post, setPost] = useState("");

     const getPostById = async(postID)=>{
        await axios.get(`http://localhost:5000/posts/post/${postID}`)
            .then((response) =>{
                dispatch(setLoading(true));
                dispatch(setSuccess(true));
                dispatch(setLoading(false));
                response.data.message.map((post, index) =>{
            
                    setPost(post); // I think it's complaining about this line
                });
            }).catch((error) =>{
                console.log("err: ", error);
                dispatch(setLoading(true));
                dispatch(setSuccess(false));
                dispatch(setLoading(false));
                dispatch(setMessage(`${error}`));
            });
    };

    useEffect(() =>{
        getPostById(testPostID);
    }, []);
    
}

我收到以下错误:

警告:无法对未挂载的组件执行 React 状态更新。这是一个空操作,但它表示应用程序中存在内存泄漏。要修复此问题,请取消 %s.%s 中的所有订阅和异步任务,这是一个 useEffect 清理函数, 在 ABCComponent 中。

我试过什么:我尝试删除 async/await,希望它能解决问题,但事实并非如此。

解决这个问题的最佳方法是什么?

javascript reactjs react-native 异步-await axios

评论

0赞 Estus Flask 7/4/2022
在卸载时使用 axios 取消。

答:

0赞 Milos Pavlovic 7/4/2022 #1

当您尝试更新未挂载组件的状态时,可能会发生内存泄漏,如警告所述。为了解决这个问题,你应该包括一些标志,在更新状态之前,你将使用这些标志来检查组件是否仍然挂载。此外,我还会给你一些其他建议 - 不要将 async/await 与 .then 一起使用,您应该只使用这两种方法中的一种(async/await 是我的建议)。isMounted

你应该重写成这样的东西:

const isMounted = useRef(true);
const testPostID = "1234567891011";

const [post, setPost] = useState("");

const getPostById = async(postID)=>{
      try {
        dispatch(setLoading(true));

        const response = await axios.get(`http://localhost:5000/posts/post/${postID}`)
        
        if(isMounted.current){
            dispatch(setSuccess(true));
            dispatch(setLoading(false));
            response.data.message.map((post, index) =>{
                 setPost(post); // This part is unclear, why overriding state, and why in .map???
            });
         }
       } catch(err) {
         console.log("err: ", error);
         if(isMounted.current) {              
           dispatch(setLoading(true));
           dispatch(setSuccess(false));
           dispatch(setLoading(false));
           dispatch(setMessage(`${error}`));
         }
       }
  };

useEffect(() =>{
    getPostById(testPostID);

   return () => {
     isMounted.current = false;
   }
}, []);

此外,还有一个不清楚的部分,您正在更新状态,为什么要使用 .map,为什么要在每次迭代中覆盖状态?