0

I'm trying to update the state in a navigation component to show "Log Out" if a cookie is set. The only problem is I cannot get the cookie without refreshing the entire page. Is there a way for me to get the cookie without a refresh? The below code shows how I'm trying to get the cookie and setting the state.

Updated with code:

import React, {Component} from 'react';

import './NavigationItems.css';

import Logo from '../../Logo/Logo';

import { Route, Link } from 'react-router-dom';

import PortalFindSubscriber from '../../../containers/Portal/PortalFindSubscriber';

import Login from "../../../components/Login/Login";

import Register from "../../../components/Register/Register";

import Reset from "../../../components/Reset/Reset";

import ResetConfirm from "../../../components/Reset/ResetConfirm";

import Aux from '../../../hoc/Aux/Aux';

import Cookies from 'universal-cookie';

const cookies = new Cookies();

class navigationItems extends Component{
  constructor() {
    super();
    this.updateLoggedStatus = this.updateLoggedStatus.bind(this)
  }
  state = {
        isLogged: false,
    };
  componentDidMount() {
    this.setState({isLogged: true});
    console.log(this.state.isLogged);
    this.updateLoggedStatus();

  }
  Collapse (e) { 
    const body = document.body;
    const collapseBtn = e.target;
    const collapsedClass = "collapsed";
    collapseBtn.getAttribute("aria-expanded") === "true"
    ? collapseBtn.setAttribute("aria-expanded", "false")
    : collapseBtn.setAttribute("aria-expanded", "true");
  collapseBtn.getAttribute("aria-label") === "collapse menu"
    ? collapseBtn.setAttribute("aria-label", "expand menu")
    : collapseBtn.setAttribute("aria-label", "collapse menu");
    body.classList.toggle(collapsedClass);
  };

  Toggle(e){
    const body = document.body;
    const toggleMobileMenu = e.target;
 
    toggleMobileMenu.getAttribute("aria-expanded") === "true"
      ? toggleMobileMenu.setAttribute("aria-expanded", "false")
      : toggleMobileMenu.setAttribute("aria-expanded", "true");
    toggleMobileMenu.getAttribute("aria-label") === "open menu"
      ? toggleMobileMenu.setAttribute("aria-label", "close menu")
      : toggleMobileMenu.setAttribute("aria-label", "open menu");
    body.classList.toggle("mob-menu-opened");

  }
  
  onSignOutClick = () =>{
    cookies.remove('AccessToken');
    this.setState({isLogged: false});
  }
 updateLoggedStatus() {
   this.setState({ isLogged: true });
  }
  render () {
    cookies.addChangeListener(console.log(cookies.get('AccessToken')));
   console.log(this.state.isLogged);
    //const { isLogged } = this.state;
    return(
            <Aux>
      
      <header className="pageHeader">
        <nav>
          <Link to={"/"}>
            <Logo />
          </Link>
          <button className="toggle-mob-menu" aria-expanded="false" aria-label="open menu" onClick={this.Toggle}>
            <svg width="20" height="20" aria-hidden="true">
              <use xlinkHref="#down"></use>
            </svg>
          </button>
          <ul className="adminMenu">
            <li className="menuHeading">
              <h3>Admin</h3>
            </li>
            {cookies.get('AccessToken')!==undefined?
            <>
                       
            <li>
              <Link to={"/"} onClick={this.onSignOutClick}>
              
                <div class="material-icons" style={{marginRight: 10}}>
                  login
                </div>

                <span>Log Out</span>
              </Link>
            </li>
            </>
            :<li>
              <Link to={"/"}>
                <svg>
                  <use xlinkHref="#users"></use>
                </svg>
                <span>Log In</span>
              </Link>
            </li>}
            <li>
              <button className="collapse-btn" aria-expanded="true" aria-label="collapse menu" onClick={this.Collapse}>
                <svg aria-hidden="true">
                  <use xlinkHref="#collapse"></use>
                </svg>
                <span>Collapse</span>
              </button>
            </li>
          </ul>
        </nav>
      </header>
      <Route exact path="/" component={Login} />
      <Route exact path="/terms" component={Register} />
      <Route exact path="/reset" component={Reset} />
      <Route exact path="/reset_confirm" component={ResetConfirm} />
      <Route exact path="/find" component={PortalFindSubscriber} />
</Aux>
    );
  }
}

export default navigationItems;
Dave D
  • 41
  • 1
  • 7
  • Why should refreshing the entire page be necessary to get a cookie? Cookies come through requests and should be readable when the request arrives. You can write and read them without refreshing. Do you have a [mcve] of this? – ggorlen Oct 28 '20 at 15:38
  • @ggorlen sorry about that – Dave D Oct 28 '20 at 15:49
  • Your change listener looks wrong. `cookies.addChangeListener(console.log(cookies.get('AccessToken')));` calls the `console.log` immediately and sends `undefined` into the callback (the return value of `console.log`) instead of an actual function. You probably meant `cookies.addChangeListener(() => console.log(cookies.get('AccessToken')));`. See [this](https://stackoverflow.com/questions/16310423/addeventlistener-calls-the-function-without-me-even-asking-it-to) – ggorlen Oct 28 '20 at 15:49
  • @ggorlen one other issue I'm having is say when the user goes to "\find", this component doesn't rerender. I'm fairly new to React so I apologize if I'm not wording this correctly. – Dave D Oct 28 '20 at 16:05
  • That seems like a different issue than cookies. For starters, did the above fix your initial problem? Best to do one thing at a time. – ggorlen Oct 28 '20 at 16:12

1 Answers1

0

You Should use

boolean shouldComponentUpdate(object nextProps, object nextState)

which decided whether the component should be updated or not.

for feasible solution you can use Functional Components's UseEffect callbacks for updating states