I have a few different screen in my React project. I want only one nav for all the screens and one appLayout file. But on 3 of the screens I want SearchField
and on the others I want BackButton
. How would I achieve this?
Below is my nav code:
import React, { useEffect } from 'react';
import { Link, useHistory } from 'react-router-dom';
import { Button, Menu, MenuItem } from '@material-ui/core';
import { useDispatch, useSelector } from 'react-redux';
import './nav.css';
import { userAuthService } from '../../../services';
import { adminSelector } from '../../../reducers/admin-reducer/admin.reducer';
import { SearchField, NavIconButton, BackButton } from '../../atoms';
import { getNotificationAction } from '../../../reducers/notification-reducer/notification.actions';
import { notificationSelector } from '../../../reducers/notification-reducer/notification.reducer';
import { NotificationDropDown } from '..';
export const Nav: React.FC = ({ children }) => {
const history = useHistory();
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
const [notificationAnchorEl, setNotificationAnchorEl] = React.useState<null | HTMLElement>(null);
const { userName } = useSelector(adminSelector);
const { notifications, unseenCount } = useSelector(notificationSelector);
const dispatch = useDispatch();
useEffect(() => {
dispatch(getNotificationAction());
}, []);
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
setAnchorEl(event.currentTarget);
};
const handleNotifyClick = (event: React.MouseEvent<HTMLButtonElement>) => {
setNotificationAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
setNotificationAnchorEl(null);
};
const signOut = () => {
return userAuthService.logout().then(() => {
history.push('/');
});
};
const DropDownMenu = () => (
<Menu
id="simple-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleClose}
className="mt-12 text-black"
>
<MenuItem>
<Link to="/profile" role="menuitem">
Your Profile
</Link>
</MenuItem>
<MenuItem>
<Link to="/settings" role="menuitem">
Settings
</Link>
</MenuItem>
<MenuItem onClick={signOut}>Sign out</MenuItem>
</Menu>
);
return (
<div className="nav-container">
<div className="nav-bar-container">
<SearchField placeholder="Search" searchType="Form" onChange={() => null} />
<BackButton />
<Button onClick={handleNotifyClick}>
<NavIconButton count={unseenCount} />
</Button>
<Button
aria-controls="simple-menu"
aria-haspopup="true"
onClick={handleClick}
className="mx-1"
>
<div className="text-black text-lg font-nunito">{userName}</div>
</Button>
</div>
<NotificationDropDown
notificationAnchorEl={notificationAnchorEl}
onClose={handleClose}
count={unseenCount}
notificationProps={notifications}
/>
<DropDownMenu />
<div className="overflow-y-auto">{children}</div>
</div>
);
};
I want to do something like this:
const screenCheck = () => {
// get url location.path() --> "/individual-user" get lasyt section
// const value = ""
// if (value === location)
// setIsLocation()
And then do a check to see if the search bar or back button should show:
{isLocation ? (
<SearchField placeholder="Search" searchType="Form" onChange={() => null} />
) : (
<BackButton />
)}
My screens that need the search field are:
- /home
- /view-users
- /organisations
The ones that need the back button are:
- /create-form
- /view-users
- /individual-users
Can anyone help me with the code?
CodePudding user response:
You can can use useLocation()
from React Router Dom to know on which path you are within your Nav
, and use a conditional to show what you want. Something like this:
// at the top and outside of Nav
import { useLocation } from "react-router-dom"
// inside Nav outside of the JSX
const location = useLocation();
// inside the JSX inside Nav
{["/home", "/view-users", "/organisations"].some((item) => item === location.pathname) && (
<SearchField placeholder="Search" searchType="Form" onChange={() => null} />
)}
{["/create-form", "/view-users", "/individual-users"].some(
(item) => item === location.pathname
) && <BackButton />}