Lets say, I have a navigation bar with a few buttons(Home, Products, Jobs, etc.). All of those, but, for example, logout button, are serving with only one purpose - to navigate a user. Logout button, besides this common purpose, also has to send a query to backend to clean user's cookies, for example. Also, in case of app expanding we should make an array of buttons and map them into the component. So it kind of looks like this:
const coolButtons = [{path: '/Profile', title: 'Profile'}, {path: '/', title: 'Sign out'...}]
const testComponent = () => {
return (
<div>
{coolButtons.map((button) => (
<Button data-path={button.path}>{button.title}</Button>
))}
</div>
);
};
And then, here in the component, I also want to write a handler for all these buttons.
const handleClick = (e: React.MouseEvent<HTMLElement>) =>{
if(path)
navigate(e.currentTarget.dataset.path)// navigate from useNavigate().
}
But how could I handle logout logic aswell? Obviously the first thought that comes to mind is just to add a conditional and check if the path === sign out path and if so do its part of logic:
const handleClick = async (e) => {
const { path } = e.currentTarget.dataset;
if (path) {
if (path === '/signout') {
await logout(); // for example
navigate(path);
}
navigate(path);
}
};
But doesnt this solution seem quite buggy? What else could I do here?What if we have 2-3 buttons with uncommon logic? Thanks.
CodePudding user response:
I don't know how you build Button
component, but I'd suggest you this way. In coolButtons
object, you can create actions. For example,
const coolButtons = [{
path: '/Profile',
title: 'Profile'
}, {
path: '/',
title: 'Sign out',
action: async () => {
await logout();
}
}]
And after that, you can call that action in handleClick
const handleClick = (e) => {
const { path, action } = e.currentTarget.dataset;
if (path) {
action && action(); //if action is in your dataset, you just call it
navigate(path);
}
};