简体   繁体   中英

Why is my JS function only applying CSS to a single instance of my React component?

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;

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

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