React Native:无法在未安装的组件上执行React状态更新

当我导航到特定组件时,我的React本机应用程序将引发此错误。我正在使用功能组件。

这是我的useEffect方法。

  useEffect(() => {
    let mounted = true;
    if (mounted) {
      getSingleProject(route.params.itemId);
      console.log(singleProject && singleProject);
    }
    return () => {
      mounted = false;
      console.log("cleanup");
    };
  }, [getSingleProject, route.params.itemId])

我从其他答案尝试了另一种解决方案,但我无济于事

这是我的行动方法

export const getSingleProject = (id) => async (dispatch) => {
  console.log("This method us called");

  const config = {
    headers: {
      Authorization: await AsyncStorage.getItem("token"),
    },
  };
  await axios
    .get(`${API_URL}/project/single/${id}`, config)
    .then((res) => {
      console.log(res.data, "this is from actions");

      dispatch({
        type: GET_SINGLE_PROJECT,
        payload: res.data,
      });
    })
    .catch((err) => {
      dispatch({
        type: GET_SINGLE_PROJECT_ERROR,
        payload: err,
      });
    });
}

这是我的减速器。

export default function (state = initiastate, actions) {
  const { type, payload } = actions;

    case GET_SINGLE_PROJECT:
      return {
        ...state,
        singleProject: payload,
        loading: false,
      }; 

谢谢。

评论
  • 思密达
    思密达 回复

    What you want to do is to prevent all the state updates if the component has been unmounted (in your case it would be dispatch calls). By assigning mounted = false; you're not achieving anything since your request is already ongoing. Instead of assigning false, in the cleanup function you need to cancel that request to prevent execution of its success/error callbacks where dispatch is called.

    I'm not very familiar with axios, but according to its docs you can create a cancellation token and pass it to your axios call, so the whole solution would be something like this:

      useEffect(() => {
        const CancelToken = axios.CancelToken;
        const source = CancelToken.source();
        getSingleProject(route.params.itemId, source);
    
        return () => {
          source.cancel();
          console.log("cleanup");
        };
      }, [getSingleProject, route.params.itemId])
    
    export const getSingleProject = (id, source) => async (dispatch) => {
      console.log("This method us called");
    
      const config = {
        headers: {
          Authorization: await AsyncStorage.getItem("token"),
        },
        cancelToken: source.token
      };
      await axios
        .get(`${API_URL}/project/single/${id}`, config)
        .then((res) => {
          console.log(res.data, "this is from actions");
    
          dispatch({
            type: GET_SINGLE_PROJECT,
            payload: res.data,
          });
        })
        .catch((err) => {
          dispatch({
            type: GET_SINGLE_PROJECT_ERROR,
            payload: err,
          });
        });
    }
    
  • 薄荷情
    薄荷情 回复

    因此,将您的功能组件更改为类基础组件。然后,您可以在componentDidMount中设置一个条件,并在componentWillUnmount中将其设置为false。

    希望这可以帮助!