Eric Nguyen
Eric Nguyen

Reputation: 1046

Force State to Maintain Boolean Value

I have a banner that has it's visibility determined by the state of true or false. I have a close button with a clickHandler to set state to false, which hides the banner. When I navigate to a different page, the state resets to true, therefore the banner is visible.

How do I force the state to remain false, even if page refreshes or changes? Basically, I want the banner to not appear again, if the user closes it.

Note: Banner component is used a Layout component, which is used by all pages.

const BannerWrapper = styled.div`
  visibility: ${props => (props.show ? "visible" : "hidden")};
`

const CloseIcon = styled.div`
  position: absolute;
  cursor: pointer;
`

const Banner = () => {
  const [show, setShow] = useState(true)

  const handleClick = () => {
    setShow(false)
  }

  return (
    <BannerWrapper show={show}>
      Some Banner Content
       <CloseIcon onClick={handleClick}>
        X
      </CloseIcon>
    </BannerWrapper>
  )
}

export default Banner

Upvotes: 2

Views: 1423

Answers (2)

Drew Reese
Drew Reese

Reputation: 202801

You can persist the state to localStorage. Use a state initializer function to read in the state when the component mounts, and an useEffect hook to save/persist state updates to storage.

const Banner = () => {
  const [show, setShow] = useState(() => {
    const showBanner = localStorage.getItem('showBanner');
    // if showBanner null/undefined fallback to true
    return JSON.parse(showBanner) ?? true;
  });

  React.useEffect(() => {
    localStorage.setItem('showBanner', JSON.stringify(show));
  }, [show]);

  const handleClick = () => {
    setShow(false);
  };

  return (
    <BannerWrapper show={show}>
      Some Banner Content
       <CloseIcon onClick={handleClick}>
        X
      </CloseIcon>
    </BannerWrapper>
  );
}

Edit force-state-to-maintain-boolean-value

Update - To "reset" and display banner.

If you want/need to reset to once again display the banner then I believe any of the following will do the trick:

  • Remove it from localStorage: localStorage.removeItem('showBanner');
  • Set it true: localStorage.setItem('showBanner', JSON.stringify(true));
  • Set it null: localStorage.setItem('showBanner', null);

IMO removing it from localStorage is the cleanest option.

You could OFC also update the show state locally:

const enableBanner = () => setShow(true);

This will update the state and trigger the effect to persist the updated state value.

Upvotes: 3

Federkun
Federkun

Reputation: 36944

The answer to the question of "how do I persist values across page refresh" is: use local storage. There are hooks that implement the same kind of interface of useState, but store the value in the local storage instead of in memory under the hood. One of those is useLocalStorage ( https://usehooks.com/useLocalStorage/ ).

Upvotes: 1

Related Questions