How To Add Props to a Navbar? - javascript

I have a Navbar that contains a close button. The Navbar is a separate component, but is being brought into my AppLayout.js file. Inside my AppLayout I manage the state of the Navbar, which currently by default is set to false, and if it's false, it will not appear and a button prompting the user to open the Navbar will appear instead.
Now the problem is, inside my Navbar I have another button which fires an onClick=setShowNav(false) in order to close the Navbar, BUT the problem is that all my state for the Navbar is managed inside AppLayout, so I guess I have to pass in some prop to the Navbar component in order to get the close button to work.
I'm unsure what's the correct syntax/way to do this?

In the AppLayout file create a function :
const closeNavbarHandler = () =>{
setShowNav(false)
}
Now pass down this function as a prop to navbar component :
<Navbar onClose={closeNavbarHandler } />
Inside the Navbar component file, create a function :
const closeNavbar = () =>{
props.onClose();
}
and pass this function as onClick to the button which will close the navbar
<button onClick={closeNavbar} />

Probably there are more orthodox ways to do it (like using useContext or Redux), but you can lift up the state to the parent and pass state and setState as props to the child.

Related

reactjs - show dialog on all pages using a button component, wherever it is included

In my react app, I have a header with a show dialog button.
This header component is included in all pages as necessary.
My current logic to show the dialog is as follows:
When user clicks the button, I dispatch an action to redux store { type:SHOW_DIALOG }, and let the parent component handle the state change and draw the dialog. I am using material-UI swipeable drawer component.
Handle Click event in an iconbutton in header component...
const handleClick = () => {
/*
* temporary bypass surgery to avoid going through login dialog
* dispatch({type:'SHOW_CONTACT_INFO'})
* return;
*/
if (!isLoggedIn) dispatch({type: 'SHOW_LOGIN_DLG'})
else router.push('/my-account')
}
In the parent page, where the header is contained...
// ...other code
<Container>
{/* Whether or not to show the login dialog . */}
{loginProcessState>=1 && loginProcessState<=7
?<LoginDialog type={loginProcessState===1?"login":"otp"} />
: null}
{/* if contact edit dialog is set to show, show it. */}
{contactEditDisplay? <ProfileEditDialog />:null}
</Container>
);
But, since I have many pages (around 10 pages and server side rendering with NextJS), I will have to repeat the state management in all those pages where the dialog must be shown.
Excuse my lack of knowledge here. Is it possible to avoid this dialog state check in the parent component / page. If so, how can i do it?
Suggestion:
Move the LoginDialog component up and render it directly within the root <App/> component.
And then use React.useContext to call that dispatch in various components to trigger loginProcessState.
The above should help you render the Login acros all components.

What exacly does NextJS Link component trigger and how to catch that event

I developed a simple navbar that has a JSON as data to dynamically construct its links. Visually, I need to persist the navbar with the current active link/route. I tested out two ways:
First implementation:
Menu component:
const ToggleMenuHandler = (e: React.MouseEvent<HTMLElement>) => {
clearMenu();
activateItem(e.currentTarget);
e.stopPropagation();
}
const MenuItems = MenuContent.map(item => {
return (
<NavigationItem key={uuidv4()} {...item} clickHandler={ToggleMenuHandler} />
);
});
Navigation item component:
<ListItem onClick={(event: React.MouseEvent<HTMLElement>) => props.clickHandler(event)}>
<Link href={sub.href}>{sub.name}</Link>
</ListItem>
I'm sure that ToggleMenuHandler function is working properly after debugging it. activateItem is the function responsible for styling an item as active. If I remove the <Link> component from the navigation item, it works just fine. So I figured my menu component was being remounted, which led me to the second implementation.
Second implementation
This one was based on the principle that my menu was being remounted. What I did was to bind the href property of <Link> to the NavigationItem's id. That way, by using router.pathname I could find the item that should be activated, and the code menu component changed to:
const router = useRouter();
useEffect(() => {
activateItem(document.querySelector(`#${router.pathname}`))
}, []);
...and I also removed the ToggleMenuHandler from the menu item component. That way, when the page was redicted I would get its path and, with it, find the list item to activate visually. I also debbug the useEffect hook and it was working properly. However, it was not activated when the Link was clicked.
Question:
What exactly is triggered when a NextJS Link component is clicked, and given the context of this question, how can I handle that event?
I don't really know how the Next.js Link component works but I know that it does not need a click event handler.
Also, there should be an <a> tag inside the Link component to work properly as a link according to the docs.
I also have personally experienced if we use another element inside the Link component, it does not work like a link but navigates.

In React how to stop rendering components which state or props not changed?

I got an issue in my project , that I had a main component which acts as the parent component of my project inside that I had the routes for the other components and some other component which are directly imported into it like a Side Navbar Component and Login Component so which are triggered on an event button click , but when I open those components all the other components are re-rendering .
export const AppFramework = (props) => {
const [isOpen, setIsOpen] = useState(false);
const [isSideNav, setIsSideNav] = useState(false);
const OptimizedRoutes = React.memo(AppRoutes);
useEffect(() => {
console.log('AppFramework Mounted');
}, []);
// Methods For Opening and closing of Login and SideNav
const handleOpen = useCallback(() => {
setIsOpen(true);
}, [isOpen]);
const handleClose = useCallback(() => {
setIsOpen(false);
}, [isOpen]);
const openSideNav = useCallback(() => {
return setIsSideNav(true);
}, [isSideNav]);
const LoginPopBody = (
<div className="pop-window">
<Button startIcon={<Close />} onClick={handleClose}></Button>
{/* {For Fields for loggin in .........} */}
</div>
);
return (
<Router>
<HideOnScroll>
<AppBar color="default" className="app-header">
<Button startIcon={<Menu />} onClick={openSideNav}></Button> // Button To Open Side Navbar
<Button onClick={handleOpen}>Login</Button> /* Button To Open Login Popup */
</AppBar>
</HideOnScroll>
//sidenav comp passing props to open and close below
<SideNav open={isSideNav} close={setIsSideNav} />
//routes are below
<main className="main-blk">
<Suspense fallback={<div>Loading...</div>}>
<OptimizedRoutes />
</Suspense>
</main>
<Modal open={handleOpen}>{LoginPopBody} </Modal>
</Router>
);
};
export default React.memo(AppFramework);
On opening and closing of both login popup and side navbar renders every component .I tried React.memo in each component but nothing happened , I hope hooks will give a solution for this.
And one more thing while entering each input on login popup form fields also renders every components behind the login popup . what will be the solution for these issues ?
This might not be the answer you are satisfied with but most of the time these problems pop up because of the way you design/construct your components. In react planning the components is the first and in my opinion the most important thing. It can save us from a lot of trouble. In this case You need to keep the components linked but independent of each other.
I would recommend you to read https://reactjs.org/docs/thinking-in-react.html. This might help you.
Changing the state will definitely re-render the whole component. But to avoid some components to stop re-rendering or re-render on come custom state changes you can use useCallBack hook.
The following article might help.
https://kentcdodds.com/blog/usememo-and-usecallback/
You can put the other component in individual functions and use useCallback hook on those function. This way you can define on which state change should those functions be used again.
Actually the issue is resolved , actually my problem is very simple , its not a complicated problem , To open the Side Navbar and Login Component I don't need to pass a boolean value from the parent component as a Prop .
Instead of that, we can get the boolean value from the own component by a passing a boolean value to the module to be shown in my case I used Material UI's Modal and Drawer by an event like button click or any other event .
This is what I did to solve my issue . In short I made the components independent.

Send event to another class

in my web react project i have two class one "Menu" return the Menu for my dashboard (the links to change the pages "Home" , "messages" ....) and another one "Box" for show the pages (it's the container of my website pages ) so my question is how the page when i click button ?.
class menu(){
render(){
return(<button>click to go to home</button>) ;
}
}
class box(){
render (){
return(<Home>this is the home</Home>) ;
} }
You can create a parent component that has the page property and the setPage method.
Inside that component, render the toolbar and the pages. The toolbar should accept a prop that'll called onClickPage that should dispatch the setPage. For example:
const [page, setPage] = React.useState("dashboard");
....
<Toolbar onClickPage={page => setPage(page)} />
<Pages page={page} />
This is what's called Lifting the state up (https://reactjs.org/docs/lifting-state-up.html) I suggest you to read their docs. It's very beginners friendly.
If your main problem is to navigate between pages you can easily achieve this by using react-router.
https://reactrouter.com

antd Modal open and closing issue

I have some react component, which have a Modal component of popular antd lib.
This component having some prop - let's call it isOpen prop and sending it down to andt Modal component. Like that:
const SomeCustomComponent = (props) => <Modal visible={props.isOpen} ...
I'm managing state of that isOpen prop outside of that component.
const [dialogIsOpen, setDialogState] = useState(false);
<SomeCustomComponent
isOpen={dialogIsOpen}
onCloseDialog={() => setDialogState(false)}...
<button onClick={() => setDialogState(true)}...
So, all is simple.
And I've faced an issue, where after modal is opened or closes, it, for some reason, jumps to top of the body no matter what trigger I'm using onClick on
I dont want document jump to top when modal props changed.
How to fix that issue?

Categories

Resources