I have a component named "ProjectCard" and a component named "Work". In the component Work, I have created a function get_width() that gets the width of the screen and I am running that function in the useEffect Hook. I am also using useState hook that gets set inside the useEffect Hook and I am passing the state as a prop the ProjectCard Component that I am calling inside the Work Components , I have 6 of them. In the ProjectCard components, I have a function changeStyle(dType) that gets the prop and checks if it is 'Mobile'. If the condition becomes true, It gets the html element by ID and apply the CSS to it.
Now, the problem is that I have 6 ProjectCard Components inside my Work Component , but the CSS is being applied to only one of them. Can someone kindly explain this?
Work.js
import React , {useState , useEffect} from 'react';
import Navbar from './Navbar';
import ProjectCard from './ProjectCard';
import './Work.css';
function get_width()
{
var width = window.screen.availWidth;
console.log(width);
return width;
}
function Work()
{
const [device , setDevice] = useState('Desktop');
useEffect(()=>{
if(get_width() <= 450)
{
setDevice('Mobile');
}
} , [setDevice])
return(
<>
<Navbar/>
<div id="workMain">
<h1>Our Work</h1>
<div id="workButtons">
<button>All</button>
<button>Website</button>
<button>Mobile App</button>
</div>
<div id="cards">
<ProjectCard Device = {device}/>
<ProjectCard Device = {device}/>
<ProjectCard Device = {device}/>
<ProjectCard Device = {device}/>
<ProjectCard Device = {device}/>
<ProjectCard Device = {device}/>
</div>
</div>
</>
);
}
export default Work;
ProjectCard.js
import React , {useEffect} from 'react';
import './ProjectCard.css';
function changeStyle(dType)
{
if(dType === 'Mobile')
{
var card = document.getElementById("card");
card.style.marginLeft = 0;
}
console.log(dType);
}
function ProjectCard(props)
{
useEffect(()=>{
changeStyle(props.Device);
})
return(
<>
<div id="card">
<p>Website</p>
<p>RA Traders</p>
</div>
</>
);
}
export default ProjectCard;
CodePudding user response:
This statement is causing the undesired behaviour:
var card = document.getElementById("card");
With getElementById
Javascript looks for an element with id
"card", inside your document. This is not confined to the react component, mind you. The whole DOM is searched and the first matching instance is returned. The first matching element will be the same no matter which component the function is called from). Note, ideally id
should be unique in the document.
You can use ref
s here (React's recommended way for DOM manipulation). With hooks you have to use useRef
function changeStyle(dType, divElement)
{
if(dType === 'Mobile')
{
divElement.current.style.marginLeft = 0;
}
console.log(dType);
}
function ProjectCard(props)
{
const divRef = useRef();
useEffect(()=>{
changeStyle(props.Device,divRef);
})
return(
<>
<div ref={divRef}>
<p>Website</p>
<p>RA Traders</p>
</div>
</>
);
}
export default ProjectCard;
divRef.current
will hold the value of the DOM node and you can make changes accordingly