17

How can i put the routerlink in reactjs button?

I tried these two below: the first one changes the color while the second one, i don't like it since it is reloading the page.

FIRST

<Link to="/settings">
    <IconButton color="inherit">
        <SettingsIcon />
    </IconButton>
</Link>

SECOND

<IconButton color="inherit" href="/settings">
    <SettingsIcon />
 </IconButton>
Olivier Tassinari
  • 8,238
  • 4
  • 23
  • 23
Joseph
  • 7,042
  • 23
  • 83
  • 181

3 Answers3

31

@BeHappy's solution is good, but you can implement this using composition. No need to use hook.

import React from 'react';
import { Link } from 'react-router-dom';
import { IconButton } from '@material-ui/core';
import SettingsIcon from '@material-ui/icons/Settings';

export default function Component() {
  return (
    <IconButton component={Link} to="/setting">
      <SettingsIcon />
    </IconButton>
  );
}
piotros
  • 585
  • 5
  • 9
  • 5
    I tried that and got and error on Typescript :-( (No overload matches this call.) About Page – cesarlarsson Sep 15 '21 at 15:48
  • Setting `component` attribute to `Link` seems to work technically but breaks the style of the button. The button got misaligned and the grey circle indicating hover disappeared after I used this method. – cyberixae Oct 07 '21 at 14:09
  • 2
    Make sure you import `Link` from `react-router-dom` and not from `@mui/material/Link` for this to work. – Bruno Rijsman Jul 16 '22 at 14:23
6
import React from "react";
import { useHistory } from "react-router-dom";

export default function Component() {
    const history = useHistory();

    return (
        <IconButton color="inherit" onClick={() => history.push("/setting")}>
            <SettingsIcon />
        </IconButton>
    );
}
BeHappy
  • 3,705
  • 5
  • 18
  • 59
  • 1
    If you do this then the button won't behave like a link. For example it will not show link target on mouse hover, "copy URL" might not work and middle click might not open the link in a new tab/window. – cyberixae Oct 07 '21 at 14:05
1

I was able to inject a Link into IconButton as follows. This approach preserves material-ui classes and CSS styling by capturing them in a span that wraps the Link component. The same span is also used to store the forward reference ref. I'm not sure why exactly it is needed but leaving it out seemed to be generate warnings.

import React from "react";
import { IconButton } from '@material-ui/core';
import SettingsIcon from '@material-ui/icons/Settings';

export default function Component() {
  return (
    <IconButton component={React.forwardRef(
      ({children, ...props}, ref) => (
        <span {...props} ref={ref}><Link>{children}</Link></span>
      )
    )}>
      <SettingsIcon />
    </IconButton>
  )
}
cyberixae
  • 843
  • 5
  • 15