Home > Software engineering >  Show/Hide Component by passing useState Value React
Show/Hide Component by passing useState Value React

Time:08-28

I'm building a website with React and Bootstrap which would have a static footer. The footer will contain two buttons - Back, and Next. Clicking 'back' decrements an index, and clicking 'next' would increment the index. Ideally this index would keep track of which js component to show or hide using a ternary statement with with display: 'inline' or 'none'. I've tried useState in the App.js file, AND in the Footer.js file, but I am unable to pass the useState values between components it seems. Is there a better way to do this? I have provided some of my code which does not work.

Footer.js:

import React from "react";
import { useState } from "react";

const Footer = (props) => {

const [pageIndex, setPageIndex] = useState(0);

  return (
    <div className="container-lg">
      <div >
        <button 
          onClick={setPageIndex(pageIndex - 1)}
          >
          Back
        </button>
        <button 
          onClick={setPageIndex(pageIndex   1)}
          >
          Next
        </button>
      </div>
    </div>
  );
};
export default Footer;

App.js:

function App() {
  return (
    <div className="App">
      <div style={{display: Footer.pageIndex === 0 ? 'inline' : 'none'}}>
        <Component />
      </div>
      <div style={{display: Footer.pageIndex === 1 ? 'inline' : 'none'}}>
        <AnotherComponent />
      </div>
      <Footer />
    </div>
  );
}

export default App;

CodePudding user response:

Few issues with your code: 1) className, not the class in react. 2) Error in your onClick parameters. 3) You need to move state up to the App component.

const {useState} = React;

function App() {
  const [pageIndex, setPageIndex] = useState(0);

  return (
    <div className="App">
      <div style={{ display: pageIndex === 0 ? "inline" : "none" }}>
        <Component />
      </div>
      <div style={{ display: pageIndex === 1 ? "inline" : "none" }}>
        <AnotherComponent />
      </div>
      <Footer setPageIndex={setPageIndex} />
    </div>
  );
}

const Footer = ({ setPageIndex }) => {
  return (
    <div className="container-lg">
      <div className="row justify-content-between mt-5">
        <button onClick={() => setPageIndex((prev) => prev - 1)}>Back</button>
        <button onClick={() => setPageIndex((prev) => prev   1)}>Next</button>
      </div>
    </div>
  );
};

const Component = (props) => {
  return <p>Component</p>;
};
const AnotherComponent = (props) => {
  return <p>AnotherComponent</p>;
};

ReactDOM.createRoot(
    document.getElementById("root")
).render(
    <App />
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>
<div id="root"></div>

CodePudding user response:

Shift the state of the footer to be at the parent which is App.js

import React from "react";
import { useState } from "react";

const Footer = (props) => {
  const { setPageIndex, pageIndex } = props;
  return (
    <div className="container-lg">
      <div >
        <button onClick={()=> setPageIndex(pageIndex - 1)}>Back</button>
        <button onClick={()=> setPageIndex(pageIndex   1)}>Next</button>
      </div>
    </div>
  );
};
export default Footer;

and then you could pass the setPageIndex as prop to the footer.

function App() {
  const [pageIndex, setPageIndex] = useState(0);

  return (
    <div className="App">
      <div style={{ display: Footer.pageIndex === 0 ? "inline" : "none" }}>
        <Component />
      </div>
      <div style={{ display: Footer.pageIndex === 1 ? "inline" : "none" }}>
        <AnotherComponent />
      </div>
      <Footer setPageIndex={setPageIndex} pageIndex={pageIndex} />
    </div>
  );
}

export default App;
  • Related