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

时间:2020-05-17 15:06:05

标签: javascript reactjs react-native

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

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

谢谢。

1 个答案:

答案 0 :(得分:1)

您要做的是,如果已卸载组件,则阻止所有状态更新(在您的情况下为dispatch调用)。分配mounted = false;并没有实现任何效果,因为您的请求已经在进行中。在清除函数中,您需要取消该请求以防止执行调用了dispatch的成功/错误回调,而不是将false赋值。

我对axios不太熟悉,但是根据其文档,您可以创建一个取消令牌并将其传递给您的axios通话,因此整个解决方案如下所示:< / p>

  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,
      });
    });
}