How to combine ReactJs Router Link and material-ui components (like a button)?
Asked Answered
H

6

64

I need to find a solution to be able to combine together the functionality of react router with the material ui components.

For instance, I've this scenario: a router and a button. What I tried to do it is to mix them together, and restyle them.

So from a simple link

<Link className={this.getClass(this.props.type)} to={`${url}`} title={name}>{name}</Link>

I tried to create a material ui button as the following

<Link className={this.getClass(this.props.type)} to={`${url}`} title={name}>
  <FlatButton label={name} />
</Link>

but I have the following error and Javascript breaks

invariant.js?4599:38Uncaught Invariant Violation: addComponentAsRefTo(...): Only a ReactOwner can have refs. You might be adding a ref to a component that was not created inside a component's render method, or you have multiple copies of React loaded (details: https://gist.github.com/jimfb/4faa6cbfb1ef476bd105).

Do you have any idea how to manage this situation? Thank you in advance and if you need more information let me know

Hamish answered 4/7, 2016 at 15:10 Comment(1)
I have come across this problem and with material-ui, using Link sometimes breaks the style you should you react router's browserHistory and push the url manuallyKirtle
V
128

The way to do in new versions is:

import { Link } from 'react-router-dom';

// ... some code

render(){
    return (
        <Button component={Link} to={'/my_route'}>My button</Button>
    );
}

Look at this thread or this question

Voucher answered 5/12, 2019 at 3:29 Comment(0)
C
7

This works for me:

<FlatButton label="Details" 
            containerElement={<Link to="/coder-details" />} 
            linkButton={true} />

See https://github.com/callemall/material-ui/issues/850

Chumash answered 11/9, 2016 at 16:57 Comment(3)
Works great! But how do we disable the redirect when the button is disabled?Rascon
in v1 this is now component={props => <Link to="/coder-details" {...props}/>}Overdye
Solution provided by @Overdye works great but it has caveats. You can read more here: material-ui.com/guides/composition/#caveat-with-inliningEpigenous
P
6
<Button
          size="large"
          color="primary"
          onClick={() => {}}
          variant="outlined"
          component={RouterLink}
          to={{
            pathname: `enter your path name`,
          }}
        >
          Click Here
        </Button>
Point answered 1/5, 2020 at 18:37 Comment(0)
A
2

You can try this way when using typescript:

import { NavLink as RouterLink } from "react-router-dom";
import {
  Button,
  Collapse,
  ListItem,
  makeStyles,
  ListItemIcon,
  ListItemText,
} from "@material-ui/core";

type NavItemProps = {
  className?: string;
  depth: number;
  href?: string;
  icon?: any;
  info?: any;
  open?: boolean;
  title: string;
};

const NavItem: React.SFC<NavItemProps> = ({

const CustomLink = React.forwardRef((props: any, ref: any) => (
    <NavLink
      {...props}
      style={style}
      to={href}
      exact
      ref={ref}
      activeClassName={classes.active}
    />
  ));
  return (
    <ListItem
      className={clsx(classes.buttonLeaf, `depth-${depth}`)}
      disableGutters
      style={style}
      key={title}
      button
      component={CustomLink}
      {...rest}
    >
      <ListItemIcon>
        {Icon && <Icon className={classes.icon} size="20" />}
      </ListItemIcon>
      <ListItemText primary={title} className={classes.title} />
    </ListItem>
  );
})


Areaway answered 27/4, 2020 at 17:0 Comment(0)
B
1

Material UI button as React Router link To use as a React Router Link, you can use the component prop of the Button.

import { Button } from '@mui/material';
import { Link } from 'react-router-dom';

export default function MyComponent() {
  return (
    <div>
      <Button component={Link} to="/posts">
        Posts
      </Button>
    </div>
  );
}
Beginner answered 21/6, 2023 at 9:2 Comment(0)
G
0

There is no component prop on MUI Button, so I made that

const navigate = useNavigate()
        <Button
          type="button"
          variant="text"
          onClick={() => navigate(Routes.yourPath)}
        >
          Hello
        </Button>
Griddlecake answered 29/11, 2023 at 21:55 Comment(1)
Yes there is.. what is your MUI version ?Forecourt

© 2022 - 2024 — McMap. All rights reserved.