简体   繁体   中英

React Native: Can't perform a React state update on an unmounted component

my react native application throws this error when i navigate to a specific component. I am using functional component.

This is my useEffect method.

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

I have tried another solution from other answers but i doesn't help

This is my action method

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

This is my reducer.

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

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

Thank you.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM