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.
CodePudding user response:
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} />
</>
);
}
CodePudding user response:
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()}
)
CodePudding user response:
instead of
{(activeItem=='landing' ? (
<Landing changeMain={setActiveItem}/>
) : (
<></>
))}
go with
{activeItem=='landing' && (
<Landing changeMain={setActiveItem}/>
)}
CodePudding user response:
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} />
</>
);
}
CodePudding user response:
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;