javascriptreactjsreact-helmet

Set Helmet body class when element is active


I'm trying to create an image overlay with no scroll, and I therefore need to style the body when my li is active. I'm trying to do this through Helmet, but it's not working. It just says <body class=""> in the browser—no matter if a li is active or not.

The component:

import React, { useState } from "react"
import { Helmet } from "react-helmet"

export default function ToggleActive({ children, size }) {
  const [isActive, setActive] = useState("false")

  const handleToggle = () => {
    setActive(!isActive)
  }

  return (
    <li className={isActive ? size : "active"} onClick={handleToggle}>
      <Helmet>
        <body className={isActive ? null : "no-scroll"} />
      </Helmet>
      {children}
      <button onClick={handleToggle} />
    </li>
  )
}

What's wrong here?


Solution

  • I don't think this is possible with Helmet.

    Anyway, I found a solution:

    import React, { useState, useEffect } from "react"
    
    function ToggleActive({ children, size }) {
      const [elementState, setElementState] = useState(false)
    
      function handleClick() {
        setElementState(!elementState)
      }
    
      useEffect(() => {
        document.body.classList.toggle("no-scroll", elementState)
      }, [elementState])
    
      return (
        <li className={elementState ? "active" : size} onClick={handleClick}>
          {children}
          <button onClick={handleClick} />
        </li>
      )
    }
    
    export default ToggleActive