Búsqueda de sitios web

reactjs - Botones vinculados de Material UI con la API de componentes estilizados de MUI


Me gusta el aspecto de la API de Material UI Styled Component (no la biblioteca styled-component), pero estoy teniendo problemas para convertir mi componente de botón simple en un botón con enlace.

¿Cómo inserto un enlace de react-router-dom en un botón de un Componente Estilizado de MUI?

Anteriormente, el enfoque típico de la API HOC de Material UI me permitía agregar un botón de "informes" vinculado de la siguiente manera. Funciona muy bien, pero requiere mucho más código repetitivo (no mostrado aquí):

<Button
  variant="contained"
  color="primary"
  className={classes.button}
  component={Link}
  to="/reports"
>
  <ShowChartIcon className={classes.buttonIcon} />
  Reports
</Button>

#1 Enfoque Obvio: Cuando sigo este patrón e incluyo las propiedades component y to en mi propio Componente Estilizado de MUI llamado <MyButton>, recibo un error de TypeScript que dice que esas propiedades no existen.

#2 Enfoque Diferente: Siguiendo el patrón propuesto en este issue de Material UI en GitHub, el botón efectivamente enlaza a la pantalla de reportes, pero se pierden el variant y el color de MUI:

<MyButton
    variant="contained"
    color="primary"
    {...{
        component: Link,
        to: `/reports`
    } as any}
>
    <MyShowChartIcon />
    Reports
</MyButton>

#3 Enfoque de Solución Alternativa: Una opción menos deseable es envolver el botón en un <Link>. Eso sí crea un enlace funcional, pero también introduce un poco de estilo no deseado.

<Link to="/reports">
    <MyButton
        variant="contained"
        color="primary"
    >
        <MyShowChartIcon />
        Reports
    </MyButton>
</Link>

Respuesta #1

Usando la última versión de material-ui (v4.0.2) puedes usar el componente HOC creado con withStyles, pero tendrás que transformar manualmente el componente personalizado a su tipo original:

const MyButton = withStyles(
  createStyles({
    root: {
      color: 'red'
    }
  })
)(Button) as typeof Button

entonces puedes usar tu componente personalizado como lo harías con el original:

<MyButton component={Link} to="/blank-page">
  my button
</MyButton>

Aquí hay un ejemplo funcionando: https://codesandbox.io/s/createreactappwithtypescript-n6wih

Encontré esta solución en este comentario: https://github.com/mui-org/material-ui/issues/15695#issuecomment-498242520.