Home > database >  How to hide an element using useState and classList manipulation - React
How to hide an element using useState and classList manipulation - React

Time:04-21

I am trying to create a way of toggling on and off certain elements of an svg that is being used across a design, so it is reusable across the website.

To be more specific I am trying to create a toggle that will hide the red line part of the svg by entering "false" into the setter prop - so across the project this can be done where needed.

I am using useState and a sort of props system to try and achieve this however I am having trouble around the specifics - the current error I get is "ReferenceError: setter is not defined".

Is there a better way to achieve this? and what way would I go about it so setter is defined and my current approach would work?

Code below:

const LineSvg = ({setter, toggle}) => {


    return(
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 59.6 830" xmlSpace="preserve" className="capsules capsules-image-bottom-right position-absolute">
            <path id="red-line" toggle={toggle} setter={setter}  className="capsule-a capsule-foreground fill-red track-on-scroll" d="M10.4,257.6A10.39,10.39,0,0,1,20.8,268V584.4a10.4,10.4,0,0,1-20.8,0V267.9A10.37,10.37,0,0,1,10.4,257.6Z" />
            <g className="track-on-scroll">
                <path id="green-line"   d="M49.2,394.7a10.39,10.39,0,0,1,10.4,10.4v84.4a10.4,10.4,0,0,1-20.8,0V405.1A10.33,10.33,0,0,1,49.2,394.7Z" className="capsule-b fill-green" />
                <path id="blue-line"    d="M49.2,354.6A10.39,10.39,0,0,1,59.6,365v4.9a10.4,10.4,0,1,1-20.8,0v-5A10.31,10.31,0,0,1,49.2,354.6Z" className="capsule-c fill-blue" />
                <path id="grey-line"    d="M49.2,235.2a10.39,10.39,0,0,1,10.4,10.4V330a10.4,10.4,0,0,1-20.8,0V245.6a10.33,10.33,0,0,1,10.4-10.4Z" className="capsule-d fill-grey-light" />
            </g>
        </svg>
    )
}

export default LineSvg;

index.jsx


const HomePage = () => {

    const [redToggle, setRedToggle] = useState(true);

    if(setter == "false"){
        setRedToggle(false)
    } else if(setter == "true"){
        setRedToggle(true)
    }

    const onToggle = () => {
        const redLine = document.getElementById("red-line");

        if(redToggle === false){
            redLine.classList.add("capsule-hide")
        } else if(redToggle === true){
            redLine.classList.remove("capsule-hide")
        }
    }

    

    return(
        
        <Layout>
            <Hero  
                text={
                    <h1>If your software goals aren't ambitous, don't bother scrolling.</h1>
                }
                image={
                    //If nothing is to go in here empty "" needed to prevent error
                    ""
                }
            />

           
            <section className="dark-grey-section py-10">
                <Container>
                    <Row>
                        <Col sm={12} md={6}>
                            <div className="text-column">
                                <h5>What we do</h5>
                                <h4><strong>Thrive in the era of software advantage</strong></h4>
                                <p>Today’s users aren’t easily impressed.</p>
                                <p>And what it does take to impress them can be insanely difficult to build.</p>
                                <p>Insanely difficult happens to be our speciality.</p>
                                <p>Lineate helps businesses craft the software that fits their ambitious needs—quickly, reliably and future-proofed. </p>
                                <a className="btn" href="#">Learn more about our ethos</a>
                            </div>
                        </Col>
                        <Col sm={12} md={6}>
                            <div className="position-relative">
                                <CapsuleSvg image="images/2-young-men-looking-at-a-desktop-computer-in-an-office.jpg" setter="false" toggle={onToggle}/>
                                <LineSvg/>
                            </div>
                        </Col>
                    </Row>
                </Container>
            </section>

        </Layout>
        
    )
}

export default HomePage;

CodePudding user response:

I would do something like adding a prop which would look like this..

Small change in your LineSvg

const LineSvg = ({redLineActive}) => {


    return(
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 59.6 830" xmlSpace="preserve" className="capsules capsules-image-bottom-right position-absolute">
    {redLineActive ?
            <path id="red-line" className="capsule-a capsule-foreground fill-red track-on-scroll" d="M10.4,257.6A10.39,10.39,0,0,1,20.8,268V584.4a10.4,10.4,0,0,1-20.8,0V267.9A10.37,10.37,0,0,1,10.4,257.6Z" /> 
    : null }
            <g className="track-on-scroll">
                <path id="green-line"   d="M49.2,394.7a10.39,10.39,0,0,1,10.4,10.4v84.4a10.4,10.4,0,0,1-20.8,0V405.1A10.33,10.33,0,0,1,49.2,394.7Z" className="capsule-b fill-green" />
                <path id="blue-line"    d="M49.2,354.6A10.39,10.39,0,0,1,59.6,365v4.9a10.4,10.4,0,1,1-20.8,0v-5A10.31,10.31,0,0,1,49.2,354.6Z" className="capsule-c fill-blue" />
                <path id="grey-line"    d="M49.2,235.2a10.39,10.39,0,0,1,10.4,10.4V330a10.4,10.4,0,0,1-20.8,0V245.6a10.33,10.33,0,0,1,10.4-10.4Z" className="capsule-d fill-grey-light" />
            </g>
        </svg>
    )
}

export default LineSvg;

Then in your index you could do something like this. Im not sure how you plan on toggling it so adjust to how you plan to toggle it.

...
const [redToggle, setRedToggle] = useState(true);
...
return (
...
<LineSvg redLineActive={redToggle}/>
<button onClick={() => setRedToggle(!redToggle}>Toggle</button>
...

There are some other ways to do it if you want multiple red line svg's but let me know.

  • Related