Reputation: 783
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?
Upvotes: 3
Views: 920
Reputation: 29315
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.
Upvotes: 2
Reputation: 315
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
Upvotes: 0