#StackBounty: #javascript #reactjs #react-hooks Using Location State in Functional Component

Bounty: 50

I’m working on a React project that requires the app URL to be fully-declared, static and immutable, so just:

https://exampleurl.com/path/to/app/index.html

..but none of the following:

https://exampleurl.com/path/to/app/

https://exampleurl.com/path/to/app/index.html?query=value

https://exampleurl.com/path/to/app/subdir/index.html

So, the project uses state and withRouter to provide basic app navigation. The responsible component is as follows:

import React from 'react';
import { withRouter} from "react-router-dom";
import RenderNav from './RenderNav';
import Cohort from '../view/Cohort';
import Holdings from '../view/Holdings';
import Policy from '../view/Policy';
import Search from '../view/Search';
import Start from '../view/Start';
import Training from '../view/Training';
import WatchList from '../view/WatchList';

class RenderDisplay extends React.Component {
  constructor(props) {
    super(props);
    this.state = this.props.location.state || { activeDisplay: 'start' };
    this.props.history.replace(this.props.location.pathname, this.state);
  }

  componentDidUpdate(prevProps, prevState) {
    if (this.props.location !== prevProps.location) {
      this.setState(this.props.location.state);
    }
  }

  setDisplay() {
    let displayMode = [];
    let d = this.state.activeDisplay;

    switch(d) {
      case 'start': displayMode = [
        <Start key={`display-${d}`} />
      ]; break;

      // ...and so on - activeDisplay determines displayMode (and so screen contents)

      default: displayMode = [<div>Error</div>]; break;
    }; return displayMode;
  }

  render() {
    return (
      <div className="container">
        {this.setDisplay()}
      </div>
    );
  }
}

export default withRouter(RenderDisplay);

The location.state object is set by the <Link /> component:

<Link to={{ state: {activeDisplay: 'start'} }}>
  <button type="button">Home</button>
</Link>

The result is normal browser navigation throughout the app while the URL remains unchanged.

My question is: how can the class-based RenderDisplay component above be converted to a functional component (using hooks)?

I’ve tried several permutations of useEffect, useState, and useLocation, but I clearly don’t understand hooks well enough to reproduce the behavior of the class-based component above.


Get this bounty!!!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.