Home > Net >  How to avoid state data from being shown after refresh?
How to avoid state data from being shown after refresh?

Time:08-22

I have 2 components, A and B.

  • In component B, I am getting a value from an API request that I am sending to component A on click of a button present in B.

  • In component B:

    axios.get('<api url>').then(res => {
      this.props.navigate('/', { data: res.data.successMsg })
    }) 
    

So on click of button in B, if the API works properly, I will be redirected to component A, and I can use this successMsg to show an alert with success message. Till here it is fine.

Now When I refresh this page, it again shows the success message. I use the useLocation hook in component A to check for the state:

import { useLocation } form 'react-router-dom';

export function B(){
  const [showAlert, setShowAlert] = useState(false)
  const location1 = useLocation();

  useEffect(() => {
    if (location1.state !== null) {
      setShowAlert(true)
      window.setTimeout(() => {
        location1.state = null
      }, 8000)
    }
  }, [])
}

export default B

This if statement also work every time I refresh the page, so it makes no difference and renders the success message on every reload, which I don't want. I just want the success alert to show after redirection, ie button click. How do I differentiate between refresh and redirect so that I can stop the message on refresh? or if there is some of other option/idea, please let me know. Note: I already tried the performance option, but on both redirect and refresh, it showed me the 'reload' option only.

CodePudding user response:

You can differentiate between the two using the window object:

if (window.performance && (window.performance.navigation.type === "1")) {
    //It was a refresh
} else {
    //Something else
}

Alternatively you can use this:

if (window.performance.getEntriesByType("navigation")[0].type === "reload") {
    //reload
} else {
    //something else
}

CodePudding user response:

You can't mutate the location object. You will need to manually clear the passed route state in the target component. Issue a redirect to the current path sans any state.

Example:

import { useLocation, useNavigate } form 'react-router-dom';

export function B(){
  const { pathname, state } = useLocation();
  const navigate = useNavigate();

  const [showAlert, setShowAlert] = useState(state !== null);

  useEffect(() => {
    if (showAlert) {
      window.setTimeout(() => {
        navigate(pathname, { replace: true });
      }, 8000);
    }
  },[])

  ...
}

export default B;
  • Related