skip to Main Content

I have some code where I’m rendering some components in react based off a current route

import Confirmation from './containers/Confirmation';

...

ReactDom.render(
  <Provider store={store}>
    <Router history={history} onUpdate={scrollToTop}>
      <Route exact path={BASKET} component={Main} />
      <Route path={DELIVERY} component={Main} />
      <Route path={ADDRESS} component={Main} />
      <Route path={COMPLETE} component={Confirmation} onEnter={checkOrderComplete(store)} />
    </Router>
  </Provider>,
  document.getElementById('checkout-target')
);

...

const checkOrderComplete = (store) => (nextState, replace) => {
  const state = store.getState();

  const orderCompleted = state.basket.pubOrderNumber !== '';

  if (!orderCompleted) {
    Logger.error(`incomplete order ➜ redirect to ${BASKET}`);

    replace({ pathname: BASKET });
  }
};

onEnter is no longer working since upgrading to v5. How can I achieve the same functionality with the upgraded version?

2

Answers


  1. one solution I can find since onEnter is no longer available in v5 is to pass onEnter as props to the component within the route instead:

    <Route path={COMPLETE}>
      <Confirmation onEnter={() => onEnter={checkOrderComplete(store)}/>
    </Route>
    

    now from your Confirmation component you run this function passed as state when the component mounts:

    const Confirmation({onEnter}) => {
     //...
    useEffect(() => {
     onEnter();
    },[])
    }
    

    I don’t really know if there is a better solution.

    Login or Signup to reply.
  2. I’d suggest creating a protected route component that does the check when it mounts. The idea here is that the custom route accesses the Redux store and computes the orderCompleted derived state value and conditionally returns the route content or redirects to the basket route.

    Something like the following.

    const CompletedRoute = props => {
      const state = store.getState();
    
      const orderCompleted = state.basket.pubOrderNumber !== '';
    
      useEffect(() => {
        if (!orderCompleted) {
          Logger.error(`incomplete order ➜ redirect to ${BASKET}`);
        }
      }, [orderCompleted]);
    
      return orderCompleted ? (
        <Route {...props} />
      ) : (
        <Redirect to={{ pathname: BASKET }} />
      );
    };
    
    ReactDom.render(
      <Provider store={store}>
        <Router history={history} onUpdate={scrollToTop}>
          <Route exact path={BASKET} component={Main} />
          <Route path={DELIVERY} component={Main} />
          <Route path={ADDRESS} component={Main} />
          <CompletedRoute path={COMPLETE} component={Confirmation} />
        </Router>
      </Provider>,
      document.getElementById('checkout-target')
    );
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search