简体   繁体   中英

How do I implement conditional rendering in a functional React component?

I want to implement conditional rendering in a functional React component. I don't know how to do this in a function.

I need the corresponding imported component to be rendered depending on the state.

I wrote this logic using the ternary operator and everything works, but this code is terrible and unreadable.

import React, {useState, useEffect} from 'react';

import Header from './header/header';
import Footer from './footer/footer';

// One of these components will be rendered between Header and Footer ↓
// Name of the component in the state (activeItem)

import Landing from './landing/landing';
import BookingManagement from './bookingManagement/BookingManagement';
import BookingTickets from './bookingTickets/bookingTickets';
import EnterProfile from './enterProfile/enterProfile';
import PersonalArea from './personalArea/personalArea';
import Register from './register/register';
import SearchResults from './searchResults/searchResults';
import ChoosePlace from './choosePlace/choosePlace';


function App() {
    
    const [activeItem, setActiveItem] = useState('landing');
    
    
     useEffect(() => {
        console.log(activeItem)
      });

  return (
       <>
      
      
          <Header changeMain={setActiveItem}/>
            
      
    
       {(activeItem=='landing' ? (
        <Landing changeMain={setActiveItem}/>
      ) : (
        <></>
      ))}
        {(activeItem=='bookingManagement' ? (
        <BookingManagement />
      ) : (
        <></>
      ))}
          {(activeItem=='bookingTickets' ? (
        <BookingTickets />
      ) : (
        <></>
      ))}
        {(activeItem=='enterProfile' ? (
                <EnterProfile />
              ) : (
                <></>
         ))}
          {(activeItem=='personalArea' ? (
                <PersonalArea />
              ) : (
                <></>
         ))}
           {(activeItem=='register' ? (
                <Register/>
              ) : (
                <></>
         ))}
             {(activeItem=='searchResults' ? (
                <SearchResults/>
              ) : (
                <></>
         ))}

           {(activeItem=='choosePlace' ? (
                <ChoosePlace />
              ) : (
                <></>
         ))}
          
          
          
          
          
          
      
          <Footer changeMain={setActiveItem}/>
       </>
  );
}

export default App;

I definitely need to implement this in the functional component, because I use hooks.

instead of {(activeItem=='landing'? ( ): ( <></> ))} go with {(activeItem=='landing' && )}

you can go with react-router implementation. Or if you want to handle the same in this component you can do similar like below

const getComponent = ()=>{
      if(condition1){
       return <Component1/>
      }else if(condition2){
       return <Component2/>
      }
      return <DefaultComponent/>
   
    }
 and inside the render return you can call that function like below
 return(
    {getComponent}
)

How about

const ComponentMap = {
  landing: Landing,
  bookingManagement: BookingManagement,
  bookingTickets: BookingTickets,
  enterProfile: EnterProfile,
  personalArea: PersonalArea,
  register: Register,
  searchResults: SearchResults,
  choosePlace: ChoosePlace
};

function App() {
  const [activeItem, setActiveItem] = useState("landing");

  useEffect(() => {
    console.log(activeItem);
  });

  const ActiveComponent = ComponentMap[activeItem] || React.Fragment;
  const ActiveComponentProps = {};
  if (activeItem === "landing") {
    ActiveComponentProps.changeMain = setActiveItem;
  }
  
  return (
    <>
      <Header changeMain={setActiveItem} />
      <ActiveComponent {...ActiveComponentProps} />
      <Footer changeMain={setActiveItem} />
    </>
  );
}

function App() {

const [activeItem, setActiveItem] = useState('landing');

const itemToComponent = [
  landing: {component: Landing},
  bookingManagement: {component: BookingManagement},
  ...
]
const Components = itemToComponent[activeItem].component

return (

  {<Components />}
      <Footer changeMain={setActiveItem}/>
   </>

); }

export default App;

You can create an object which wraps all your components and then use the correct component by using activeItem as the key:

    import React, {useState, useEffect} from 'react';

    import Header from './header/header';
    import Footer from './footer/footer';

    import Landing from './landing/landing';
    import BookingManagement from './bookingManagement/BookingManagement';
    import BookingTickets from './bookingTickets/bookingTickets';
    import EnterProfile from './enterProfile/enterProfile';
    import PersonalArea from './personalArea/personalArea';
    import Register from './register/register';
    import SearchResults from './searchResults/searchResults';
    import ChoosePlace from './choosePlace/choosePlace';

    const components = { Landing, BookingManagement, BookingTickets, EnterProfile, PersonalArea, Register, SearchResults, ChoosePlace };

    export default function App() {
      const [activeItem, setActiveItem] = useState("Landing");
      const ActiveItemComponent = components[activeItem];

      return (
        <>
          <Header changeMain={setActiveItem} />
          <ActiveItemComponent />
          <Footer changeMain={setActiveItem} />
        </>
      );
    }

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