0

Using React Router, I want to navigate to one of three pages, conditionally, depending on the result of an API call, but I am having trouble figuring out how can that be done.

I have tried returning ConditionalLink with the route in the if/else and wrapping the button with that instead of Link in the JSX but that does not seem to work (perhaps because the JSX has already been rendered at the time the form is submitted/next button is clicked?).

I have seen a number of other questions/answers for doing this within the router itself, but this API call and subsequent decision happen in an individual component.

EDIT: I cannot use hooks because this is a class-based component and has to remain one because of other constraints.

Code for the basic logic of the API call:

onSubmit = (event) => {

        setByValue('showLoadingSpinner', true);

        api.dataLookup(query)
            .then(data => {
                setByValue('showLoadingSpinner', false)
                saveDetails(data)
                if (data.isValid) {
                    // Navigate to first page
                } else {
                    // Navigate to second page
                }
            })
            .catch(error => {
                setByValue('showLoadingSpinner', false)
                console.log(error)
                // Navigate to third page
            })
    }
}

The JSX (the "nextButton" is nested in a form that calls onSubmit):

<div className={classes.button}>
    <Link to="/nextpage">
        <NextButton text="Next"/>
    </Link>
</div>
sjannette
  • 65
  • 1
  • 3
  • 12

1 Answers1

1

You just have to use the useHistory hook to get a history object, and then you can use history.push(someUrl) to send your user wherever you want from your AJAX callback.

const history = useHistory();

return (<div className={classes.button}>
  <Link to="/nextpage">
      <NextButton text="Next" history={history}/>

// ...


onSubmit = (event) => {
    setByValue('showLoadingSpinner', true);
    api.dataLookup(query)
        .then(data => {
            setByValue('showLoadingSpinner', false)
            saveDetails(data)
            if (data.isValid) {
                history.push('/foo');

See this for further details: https://reacttraining.com/react-router/web/api/Hooks/usehistory

machineghost
  • 33,529
  • 30
  • 159
  • 234
  • I cannot use hooks because it is (out of necessity) a class-based component. I should have included that in the question, I will edit it to specify that. – sjannette Apr 17 '20 at 18:31
  • 1
    In that case see: https://stackoverflow.com/questions/42701129/how-to-push-to-history-in-react-router-v4 – machineghost Apr 17 '20 at 19:09