1

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>
   )
}

3 Answers 3

2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Yup, that's exactly what I've been looking for! I pasted your code and changed props in buttons to clickHandler={changeCycle} and clickHandler={changeButtonName} and it works just fine. Easy thing but I had complete mind block. Thanks a lot.
0

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>
  );
};

Comments

0

update your code like

<AppButton onClick={()=> {
  changeButtonName && changeButtonName();
  changeCycle && changeCycle();
 }}>
  {text}
</AppButton>

2 Comments

Didn't help.TypeError: changeButtonName is not a functionon.
got it.. you are sending it one button but not is another

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.