简体   繁体   中英

react gatsby: adding css class dynamically not working in prod build

I need to add a css class dynamically on a div. For this I've set the css class like this:-

const Container = ({ divClass }) => {
  const [cssClass, setcssClass] = useState(divClass)
  return (
    <div id="containerDiv" className={cssClass} ></div>
    {/* <div id="containerDiv" className={divClass} ></div>   even this doesn't work*/}
  )
}

This works as expected in development build, but doesn't work in prod build. Even without using state if I set class to divClass it's not working in prod build.

It only works after I set state using setcssClass , like this-

const Container = ({ divClass }) => {
  const [cssClass, setcssClass] = useState(divClass)
  return (
    <div id="containerDiv" className={cssClass} onClick={() => setcssClass('testtt')}></div>
  )
}

Can anypone please explain this discrepancy in development and production build?

Your code is not working on your first try because at the moment you are defining const [cssClass, setcssClass] = useState(divClass) , your <div> and it's class ( divClass or cssClass ) is not defined yet.

The solution is to use a useEffect hook with empty deps ( [] ) since it's a function that is triggered once the DOM tree is loaded (and your <div> in it).

I wouldn't recommend the approach of the other answer (besides being effective) because it impacts directly the DOM and that's the reason why you are using React and not jQuery (you creating a virtual DOM to manipulate). You can achieve the same result by using a React-based approach with useRef hook.

const Container = ({ divClass }) => {
  const containerDivRef = useRef(null);
  

  useEffect(() => {
    containerDivRef.current.classList.add(divClass)
  }, []);

  return (
    <div ref={containerDivRef}></div>
  )
}

Your <div> information is stored inside the containerDivRef.current exactly in the same way that using document.querySelector but without affecting the DOM.

The discrepancy that you mention between develop and build is caused by the webpack's assets treatment and Gatsby's configuration. Since with a gatsby develop (runtime) allows you to use browser's APIs (such as window , document , other global or DOM objects) in the gatsby build (buildtime) the code is processed in the server-side, where those variables are not allowed (even created), that's why you usually should wait for them. You can check for further details in the Overview of the Gatsby Build Process documentation .

const Container = ({ divClass }) => {
  useEffect(() => {
    const containerDiv = document.querySelector("#containerDiv");

    containerDiv.classList.add(divClass);
  }, []);

  return (
    <div id="containerDiv"></div>
  )
}

Have you tried manipulating the dom manually inside useEffect ?

I know this might not be the most ideal solution but maybe it solves the problem. lol

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM