Reputation: 73
I wanted to make my components as reusable as it possible but when I started adding events the problems occured. I am using one button component in a lot of places in my app and I just change its name. It worked fine when I passed one onClick event to it (to change menu button name) but when I wanted to do the same with another button (to change cycle name) and when I passed second onClick event to the same button component the menu button stopped working. I tried to find solution but found only different topics. I know I could make a wrapper around the button and make onClick on the wrapper, but I think I am doing something wrong and there must be more elegant way to handle this.
Button component
export const Button = ({text, changeButtonName, changeCycle}) => {
return (
<AppButton onClick={changeButtonName, changeCycle}>
{text}
</AppButton>
);
};
Navbar component where cycle and menuu buttons are placed
export const Navbar = () => {
const menuButton = 'Menu';
const closeButton = 'Zamknij';
const [menuButtonName, setMenuButtonName] = useState(menuButton);
const changeButtonName = () => {
menuButtonName === menuButton ? setMenuButtonName(closeButton) : setMenuButtonName(menuButton);
}
const interiorButton = 'Interior →';
const structuralCollageButton = 'Structural Collage →';
const [cycleButtonName, setCycleButtonName] = useState(interiorButton);
const changeCycle = () => {
cycleButtonName === interiorButton ? setCycleButtonName(structuralCollageButton) : setCycleButtonName(interiorButton);
}
return (
<Nav>
<AuthorWrapper>
<AuthorName>
Michał Król
</AuthorName>
<AuthorPseudonym>
Structuralist
</AuthorPseudonym>
</AuthorWrapper>
<CycleButtonWrapper >
<Button text={cycleButtonName} changeCycle={changeCycle} />
</CycleButtonWrapper>
<MenuButtonWrapper>
<Button text={menuButtonName} changeButtonName={changeButtonName} />
</MenuButtonWrapper>
</Nav>
)
}
Upvotes: 1
Views: 1046
Reputation: 10382
this is not a really reusable approach for a Button. For every new method name you would have to include in the props params and you could face something like:
export const Button = ({text, changeButtonName, changeCycle, changeTheme, changeDisplay})
the proper way to make it reusable would be by passing only one handler to your button:
export const Button = ({text, clickHandler}) => {
return (
<AppButton onClick={clickHandler}>
{text}
</AppButton>
);
};
fwiw, the reason you have problem is because at this code onClick={changeButtonName, changeCycle}
you are passing multiple expressions with comma operator where the last operand is returned.
Upvotes: 2
Reputation: 439
update your code like
<AppButton onClick={()=> {
changeButtonName && changeButtonName();
changeCycle && changeCycle();
}}>
{text}
</AppButton>
Upvotes: 0
Reputation: 721
You cannot pass two functions to onClick. Either do a conditional check that call that function which is passed or make a wrapper function.
export const Button = ({text, changeButtonName, changeCycle}) => {
return (
<AppButton onClick={changeButtonName || changeCycle}>
{text}
</AppButton>
);
};
or
export const Button = ({text, changeButtonName, changeCycle}) => {
return (
<AppButton
onClick={() => {
changeButtonName && changeButtonName();
changeCycle && changeCycle();
}
}>
{text}
</AppButton>
);
};
Upvotes: 0