Home > OS >  Changing CSS Attribute on click in React while using Styled Components
Changing CSS Attribute on click in React while using Styled Components

Time:11-16

I'm making a web in HTML, CSS, and plain JS. I'm planning to convert this into ReactJS. Although, I'm planning to make this into a single JSX file to export it to App.js. My friend recommended me to use Styled Components so I can make all of it into a single JSX file.

The problem is, I have a button which shows a Modal Box when clicked, using the function in plain JS. Currently, I'm having trouble implementing the function on ReactJS.

My code in React looks a bit like this:

//The Exported page
import React, {useState} from "react";
import styled from "styled-components";

export function InfoCalon(){

  return(
    <CustomStyle>
    <div >
        <button id="button1"  >Button 1</button>
    </div>

    <div id="modal" >
        <div >
            //Modal Contents
        </div>
    </div>
    </CustomStyle>
  )
}

const CustomStyle = styled.div`
background-color: black;
color: white;

.button {
  border: none;
  min-width: 30%;
  height: auto;
  display: inline-flexbox;
  text-align: center;
  text-decoration: none;
  margin: 10px 10% 10px 10%;
  transition-duration: 0.2s;
  cursor: pointer;
}


.button:hover{
  transform: scale(1.02);
}

.button:active{
  transform: scale(0.97);
  transition-duration: 0.05s;
}

.modalpopup {
  display: none;          //The attribute that I want to change on button1 click to display: block.
  position: fixed;
  z-index: 10;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  overflow: auto;
  background-color: rgba(0,0,0,0.4);
}

.modal-content {
  background-color: #102037;
  margin: 7% auto;
  position: relative;
  padding: 1% 3% 3% 3%;
  width: 80%;
}
` 

I tried using onClick in the button and made a function to show the modal, but I always failed, getting errors such as "var is null()".

Before converting to ReactJS, the code in the JS file was:

var btn1 = document.getElementById("button1");

btn1.onclick = function() {
  modal.style.display = "block";
}

For the HTML and CSS code, it's pretty much everything that's in CustomStyle.

I would appreciate any response for this, thank you.

CodePudding user response:

In the InfoCalon component, you can maintain an internal state which defines whether the modal is open or not

const [isOpen, setIsOpen] = useState(false);

Now to toggle this you need to attach an event listener to the button like this

<button id="button1" onClick={(e) => setIsOpen(!isIsOpen)} class="button" >Button 1</button>

Now all you need to do is conditionally render the modal i.e. only show the modal if the isOpen is true.

{isOpen && (<div id="modal" class="modalpopup">
    <div class="modal-content">
        //Modal Contents
    </div>
</div>)}

And you also need to remove the display: none from the styles of the modal.

CodePudding user response:

styled-component are React components, so you can pass props to them. I would suggest adding a isClicked (or similar) state to the InfoCalon component and update it from a click handler attached to the button. Pass the isClicked value as a prop to CustomStyle component.

export function InfoCalon() {
  const [isClicked, setIsClicked] = React.useState(false);

  const clickHandler = () => setIsClicked(clicked => !clicked);

  return(
    <CustomStyle isClicked={isClicked}>
      <div class="content-container">
        <button id="button1" class="button" onClick={clickHandler}>
          Button 1
        </button>
      </div>

      <div id="modal" class="modalpopup">
        <div class="modal-content">
          //Modal Contents
        </div>
      </div>
    </CustomStyle>
  )
}

Use a props function to access the isClicked prop and set the display rule accordingly.

const CustomStyle = styled.div`
  ...

  .modalpopup {
    display: ${({ isClicked }) => isClicked ? "block" : "none"};
    ...
  }

  ...
`;

An improved design might be to break all the CSS up into several individual style-components, where each can take their own props. You could for example, make the modal div its own component and pass an isOpen prop directly to it to set the style.

Example

const Modal = styled.div`
  display: ${({ isOpen }) => isOpen ? "block" : "none"};          
  position: fixed;
  z-index: 10;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  overflow: auto;
  background-color: rgba(0,0,0,0.4);
`;

const ModalContent = styled.div`
  background-color: #102037;
  margin: 7% auto;
  position: relative;
  padding: 1% 3% 3% 3%;
  width: 80%;
`;

export function InfoCalon() {
  const [isOpen, setIsOpen] = React.useState(false);

  const toggleModal = () => setIsOpen(open => !open);

  return(
    <CustomStyle isClicked={isClicked}>
      <div class="content-container">
        <button id="button1" class="button" onClick={toggleModal}>
          Button 1
        </button>
      </div>

      <Modal id="modal">
        <ModalContent>
          // Modal Contents
        </ModalContent>
      </Modal>
    </CustomStyle>
  )
}
  • Related