1

I am trying to maintain the state of the previously selected tab after page reload. After reading several articles, it seems that using query params is a more effective choice considering the current situation rather than Redux when scaling. Can anyone show an example or demo if possible of how I might structure it to be adapted and used in my current structure? Thanks for considering.

Here are the imports:

import React from 'react';
import AppBar from '@material-ui/core/AppBar';
import CssBaseline from '@material-ui/core/CssBaseline';
import Drawer from '@material-ui/core/Drawer';
import Hidden from '@material-ui/core/Hidden';
import IconButton from '@material-ui/core/IconButton';
import MenuIcon from '@material-ui/icons/Menu';
import Toolbar from '@material-ui/core/Toolbar';
import Typography from '@material-ui/core/Typography';
import {withStyles } from '@material-ui/core/styles';
import SearchBar from '../TopBar/SearchBar'
import Home from '../Screens/Home'
import Contact from '../Screens/Contact'
import Profile from '../Screens/Profile'
import Settings from '../Screens/Settings'
import Messages from '../Screens/Messages'
import Products from '../Screens/Products'
import Tabs from "@material-ui/core/Tabs";
import Tab from "@material-ui/core/Tab";
import { Switch, Route, Link, BrowserRouter} from "react-router-dom";

Here is the beginning of the class component:

class StaticComponents extends React.Component {
  constructor(props) {
    super(props);
      this.state = { 
       values: 0,
        mobileOpen: false,
        active: true,
        width: window.outerWidth,
        height: window.outerHeight

       };
    this.handleChange = this.handleChange.bind(this);
    this.handleDrawerToggle = this.handleDrawerToggle.bind(this)
    this.closeDrawer = this.closeDrawer.bind(this)
    this.activAte = this.activAte.bind(this)
    this.updateDimensions = this.updateDimensions.bind(this);
    //binds the function not its variable
    }
    componentWillUpdate() {
      window.addEventListener("resize",this.updateDimensions);

    }


  handleChange=(_,values)=>this.setState({ values });

 updateDimensions() {
    this.setState({
      height: window.outerHeight, 
      width: window.outerWidth
    });
  }
  handleDrawerToggle(){
    const toggleDrawer= this.state.mobileOpen === false ? true : false;
    this.setState({mobileOpen: toggleDrawer})

  }

  closeDrawer(){
    this.setState({mobileOpen: false})
  }

activAte(){
  this.setState({active: true})
}

  render(){
const homeR= this.state.active
const {classes} = this.props;
const {values}= this.state
const widthS= this.state.width

Here is the drawer variable holding the tab structure:

const drawer = (
  <Route
    path="/"
    render={() => (
      <nav>
        <div style={{ left: 70, position: 'relative', marginTop: 40 }}>
          <VerticalTabs
            value={values}
            variant="fullWidth"
            onChange={this.handleChange}
          >
            <MyTab
              component={Link}
              to="/"
              disableRipple={widthS < 599 ? true : false}
              onClick={this.handleDrawerToggle}
              icon={
                <svg
                  version="1.1"
                  id="Capa_1"
                  xmlns="http://www.w3.org/2000/svg"
                  xlink="http://www.w3.org/1999/xlink"
                  x="0px"
                  y="0px"
                  width="460.298px"
                  height="460.297px"
                  viewBox="0 0 460.298 460.297"
                  space="preserve"
                  fill={values === 0 ? '#0D9DCE' : '#9B9B9B'}
                  className="home"
                >
                  {homeA}
                  {homeB}
                </svg>
              }
              label={
                <p
                  className="home-Text"
                  style={{ color: values === 0 ? 'white' : '#9B9B9B' }}
                >
                  Home
                </p>
              }
            />
            <MyTab
              component={Link}
              to="/Screens/Contact"
              disableRipple={widthS < 599 ? true : false}
              onClick={this.handleDrawerToggle}
              icon={
                <svg
                  height="512pt"
                  viewBox="0 0 512 512"
                  width="512pt"
                  xmlns="http://www.w3.org/2000/svg"
                  fill={values === 1 ? '#0D9DCE' : '#9B9B9B'}
                  className="processes"
                >
                  {ContactA}
                </svg>
              }
              label={
                <p
                  className="processes-Text"
                  style={{ color: values === 1 ? 'white' : '#9B9B9B' }}
                >
                  Contact
                </p>
              }
            />
            <MyTab
              component={Link}
              to="/Screens/Profile"
              disableRipple={widthS < 599 ? true : false}
              onClick={this.handleDrawerToggle}
              icon={
                <svg
                  version="1.1"
                  id="Capa_1"
                  xmlns="http://www.w3.org/2000/svg"
                  xlink="http://www.w3.org/1999/xlink"
                  x="0px"
                  y="0px"
                  viewBox="0 0 512.001 512.001"
                  space="preserve"
                  className="designs"
                  fill={values === 2 ? '#0D9DCE' : '#9B9B9B'}
                >
                  {ProfileA}
                </svg>
              }
              label={
                <p
                  className="designs-Text"
                  style={{ color: values === 2 ? 'white' : '#9B9B9B' }}
                >
                  Profile
                </p>
              }
            />
            <MyTab
              component={Link}
              to="/Screens/Settings"
              disableRipple={widthS < 599 ? true : false}
              onClick={this.handleDrawerToggle}
              icon={
                <svg
                  version="1.1"
                  id="Capa_1"
                  xmlns="http://www.w3.org/2000/svg"
                  xlink="http://www.w3.org/1999/xlink"
                  x="0px"
                  y="0px"
                  viewBox="0 0 512 512"
                  space="preserve"
                  className="materials"
                  fill={values === 3 ? '#0D9DCE' : '#9B9B9B'}
                >
                  {SettingsA}
                  {SettingsB}
                </svg>
              }
              label={
                <p
                  className="materials-Text"
                  style={{ color: values === 3 ? 'white' : '#9B9B9B' }}
                >
                  Settings
                </p>
              }
            />
            <MyTab
              component={Link}
              to="/Screens/Messages"
              disableRipple={widthS < 599 ? true : false}
              onClick={this.handleDrawerToggle}
              icon={
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  xlink="http://www.w3.org/1999/xlink"
                  width="512"
                  height="512"
                  viewBox="0 0 60 60"
                  version="1.1"
                  className="printers"
                  fill={values === 4 ? '#0D9DCE' : '#9B9B9B'}
                >
                  {MessagesA}
                  {MessagesB}
                  {MessagesC}
                  {MessagesD}
                  {MessagesE}
                  {MessagesF}
                </svg>
              }
              label={
                <p
                  className="printers-Text"
                  style={{ color: values === 4 ? 'white' : '#9B9B9B' }}
                >
                  Messages
                </p>
              }
            />
            <MyTab
              component={Link}
              to="/Screens/Products"
              disableRipple={widthS < 599 ? true : false}
              onClick={this.handleDrawerToggle}
              icon={
                <svg
                  height="512pt"
                  viewBox="0 0 512 512"
                  width="512pt"
                  xmlns="http://www.w3.org/2000/svg"
                  className="forum"
                  fill={values === 5 ? '#0D9DCE' : '#9B9B9B'}
                >
                  {ProductsA}
                  {ProductsB}
                  {ProductsC}
                </svg>
              }
              label={
                <p
                  className="QA-Text"
                  style={{ color: values === 5 ? 'white' : '#9B9B9B' }}
                >
                  Products
                </p>
              }
            />
          </VerticalTabs>
        </div>
      </nav>
    )}
  />
);

Here is the Routing structure of course nested within BrowserRouter:

<Switch>
  <Route path="/Screens/Contact" component{Contact} />
  <Route path="/Screens/Profile" component={Profile} />
  <Route path="/Screens/Settings" component={Settings}  />
  <Route path="/Screens/Messages" component={Messages} />
  <Route path="/Screens/Products" component={Products}  />
  <Route path="/" component={Home} />
</Switch>
Camille Basbous
  • 299
  • 5
  • 11
  • 34

1 Answers1

1

It's somewhat hard to decipher your const drawer, but I'll give it a shot. Query params are accessible from this.props.location.search. See this response. You can use /screens/profile/:param in your Router to for example pass a parameter to your profile-section. And then grab it in the child component with the mentioned above prop.

Another approach is to use the window.location property and get the pathname:

const location = window.location.pathname;
const lastSlashIndex = location.lastIndexOf('/') + 1;
const id = location.substring(lastSlashIndex)

This will find the last index of the slash and the id will contain the param you passed in through the router.

If you have multiple, you could do something along the line of this:

const paramMap = new Map();
const searchSplit = location.search.split("&");
searchSplit.forEach(item => {
    paramMap.set(item.split("=")[0], item.split("=")[1])
});

This will find all the parameters you passed in and you can access them from the paramMap const through paramMap.get("?id");, for example.

Hope I understood your question correctly :)

Alacho
  • 21
  • 1
  • 6