0

I want to click the button and render its corresponding div. Should I add the the div's info that I want to render to the state? I'm sure there's a few different ways to solve this but I want to do it the React way and maybe as a function component?

Updated

       export default function About(props) (
        const [isHidden, setIsHidden] = useState(true);

        const handleClick = () => {
        setIsHidden(!isHidden);
        };
         return (

       <div className="row justify-content-md-center">
        <div className="col-auto">
          <CustomButton onClick={handleClick}>Website Develpment</CustomButton>
        </div>
        <div className="col-auto">
          <CustomButton onClick={handleClick}>Wordpress Develpment</CustomButton>
        </div>
        <div className="col-auto">
          <CustomButton onClick={handleClick}>Ecommerce Development</CustomButton>
        </div>
      </div>

      <div className="row">
        <div className="col-md-4">column 1</div>
        <div className="col-md-4">column 2</div>
        <div className="col-md-4">column 3</div>
      </div>
     );
    )
2
  • When you click a button, and a div is rendered, and you then click a different button, do you want it to also show, or should it replace the original div? Commented Aug 27, 2020 at 13:43
  • It should replace the original. Commented Aug 27, 2020 at 13:45

4 Answers 4

1

You can store an ID as a string state variable, and set that variable on button press.

Then use ConditionalRendering to only display the div with the matching ID.

const {useState} = React;

function About(props) {
  const [visibleItem, setVisibleItem] = useState('');
  return (
    <div>
      <button onClick={() => setVisibleItem("website")}>
        Show Website Develpment
      </button>
      <button onClick={() => setVisibleItem("wordpress")}>
        Show Wordpress Develpment
      </button>
      <button onClick={() => setVisibleItem("ecommerce")}>
        Show Ecommerce Development
      </button>
      
      {visibleItem === "website" && 
        <div>
          <h2>Wordpress Development</h2>
          <p>Info about Wordpress and all the things I can do with it</p>
        </div>
      }     
      
      {visibleItem === "wordpress" && 
        <div>
          <h2>Ecommerce Development</h2>
          <p>I can do eccomerce things too</p>
        </div>
      }      
      
      {visibleItem === "ecommerce" && 
         <div>
          <h2>Website Development</h2>
          <p>Info about Webdev</p>
        </div>
      }
      
    </div>
   );
}

ReactDOM.render(
  <About/>,
  document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>

If the sections were much bigger then I'd recommend splitting them out into separate components, or maybe doing an if or switch statement to select between them before the return, but the above snippet is a pattern I have used often with react.

Sign up to request clarification or add additional context in comments.

2 Comments

why do need to functions here? const handleClick = (item) => () => setVisibleItem(item);
Sorry forgot to delete when I moved the functions to the buttons
0

You can create two states one holding array of button info to minimize repetition of code and another state to track the column clicked.

 import React, { useState } from "react";
    
    export default function About(props) {
      const [colNum, setColNum] = useState('');
      const [btnNames] = useState([
        {
          colId: 1,
          name: "Website Develpment"
        },
        {
          colId: 2,
          name: "Wordpress Develpment"
        },
        {
          colId: 3,
          name: "Ecommerce Develpment"
        }
      ]);
    
      const handleClick = (id) => {
        setColNum(id);
      };
    
      return (
        <>
          <div className="row justify-content-md-center">
            {btnNames.map(element => (
              <div className="col-auto" key={element.colId}>
                <CustomButton onClick={()=> handleClick(element.colId)}>{element.name}</CustomButton>
              </div>
            ))}
          </div>
    
          {colNum !== '' ? (<div className="row">
            <div className="col-md-4">column {colNum}</div>
            </div>) : null }
          
        </>
      );
    }

Comments

0

So you can define showing value for each section in state, which initial should be false. Then we can handle this state with a function where built-in JS tools can be used (Object.entries, Object.fromEntries and map). The element will be displayed, the value of which will be true, and the rest will automatically become false. More details can be found here: https://codesandbox.io/s/happy-sea-nckmw?file=/src/App.js

import React, { useState } from "react";
import "./styles.css";
import styles from "./TestStyles.module.css";
import CustomButton from "./CustomButton";

export default function App() {
  const [showDiv, setShowDiv] = useState({
    web: false,
    wordpress: false,
    ecommerce: false
  });

  const showDivHandler = (val) => {
    const newState = Object.fromEntries(
      Object.entries(showDiv).map(([key, value]) => [key, (value = false)])
    );

    setShowDiv({
      ...newState,
      [val]: !showDiv[val]
    });
  };

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <div className={styles.Section}>
        <div className="col-auto">
          <CustomButton clicked={() => showDivHandler("web")}>
            Website Develpment
          </CustomButton>
        </div>
        <div className="col-auto">
          <CustomButton clicked={() => showDivHandler("wordpress")}>
            Wordpress Develpment
          </CustomButton>
        </div>
        <div className="col-auto">
          <CustomButton clicked={() => showDivHandler("ecommerce")}>
            Ecommerce Development
          </CustomButton>
        </div>
      </div>
      <div className={styles.Section} style={{marginTop: 20}}>
        {showDiv.web && <div className={styles.Content}>column 1</div>}
        {showDiv.wordpress && <div className={styles.Content}>column 2</div>}
        {showDiv.ecommerce && <div className={styles.Content}>column 3</div>}
      </div>
    </div>
  );
}

The custom button can look like this:

import React from "react";

const button = (props) => (
  <button
    onClick={props.clicked}
    //some other props if need it(e.g. styles)
  >
    {props.children}
  </button>
);

export default button;

Comments

0

This is how I solved it. Thanks for your help!

export default function About() {
  const [visibleItem, setVisibleItem] = useState(1);

  const [priceItems] = useState([
    {
      id: 1,
      name: "website",
    },
    {
      id: 2,
      name: "wordpress",
    },
    {
      id: 3,
      name: "ecommerce",
    },
  ]);

  const handleClick = (id) => {
    setVisibleItem(id);
  };
  return (
    <div className="container-fluid pricing-wrapper">
      <div className="row">
        <div className="col">
          <h1>Pricing</h1>
        </div>
      </div>

      <div className="row">
        <div className="col">
          <p>Innovation that empowers your team while also reducing risk!</p>
          <div className="seperator"></div>
        </div>
      </div>

      <div className="row justify-content-md-center">
        <div className="row justify-content-md-center">
         {priceItems.map((item) => (
           <div className="col-auto">
              <CustomButton onClick={() => setVisibleItem(item.id)}>
               {item.name}
              </CustomButton>
          </div>
         ))}
          </div>
      </div>

      {priceItems
        .filter((item) => item.id === visibleItem)
        .map((item) => (
          <PriceItem item={item} />
        ))}
    </div>
  );
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.