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

问题描述 投票:1回答:2

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

这是我的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,
      }; 

谢谢。

javascript reactjs react-native
2个回答
0
投票

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

希望这会有所帮助!


0
投票

[您要做的是,如果该组件已卸载,则阻止所有状态更新(在您的情况下为dispatch调用)。通过分配mounted = false;,您的请求已在进行中,因此您一事无成。在清除函数中,您需要取消该请求,以防止在调用dispatch的情况下执行其成功/错误回调,而不是分配false。

我对axios不太熟悉,但是根据它的文档,您可以创建一个取消令牌并将其传递给axios调用,因此整个解决方案如下:

  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,
      });
    });
}
© www.soinside.com 2019 - 2024. All rights reserved.