在另一个(功能)组件(类型)中将 Nextjs Link 与 MUI Link 或 MUI Button 一起使用

Ale*_*Dim 1 javascript typescript reactjs next.js

我将 Next.js (10.2) 和 Material-UI (MUI) 与 Typescript 一起使用,并拥有一个自定义链接组件:

链接.tsx ( /components)

import React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import { withRouter } from 'next/router';
import NextLink from 'next/link';
import MuiLink from '@material-ui/core/Link';

function NextComposed(props) {
  const { as, href, prefetch, forwardedRef, ...other } = props;

  return (
    <NextLink href={href} prefetch={prefetch} as={as}>
      <a {...other} ref={forwardedRef} />
    </NextLink>
  );
}

NextComposed.propTypes = {
  as: PropTypes.string,
  href: PropTypes.string.isRequired,
  prefetch: PropTypes.bool,
  forwardedRef: PropTypes.any.isRequired,
  children: PropTypes.node.isRequired,
}

const NextComposedWithRef = React.forwardRef((props, ref) => <NextComposed {...props} forwardedRef={ref} />)

// A styled version of the Next.js Link component:
// https://nextjs.org/docs/#with-link
function Link(props) {
  const { activeClassName, router, className: classNameProps, naked, ...other } = props;

  const className = clsx(classNameProps, {
    [activeClassName]: router.pathname === props.href && activeClassName,
  });

  if (naked) {
    return <NextComposed className={className} {...other} />;
  }

  return <MuiLink component={NextComposedWithRef} className={className} {...other} />
}

Link.propTypes = {
  activeClassName: PropTypes.string,
  as: PropTypes.string,
  className: PropTypes.string,
  href: PropTypes.string,
  naked: PropTypes.bool,
  onClick: PropTypes.func,
  prefetch: PropTypes.bool,
  router: PropTypes.shape({
    pathname: PropTypes.string.isRequired,
  }).isRequired,
  children: PropTypes.node.isRequired,
};

Link.defaultProps = {
  activeClassName: 'active',
};

export default withRouter(Link)

Run Code Online (Sandbox Code Playgroud)

我还有另一个版本,效果很好。但问题不在于其本身Link,而是当我尝试创建另一个component包含 my 的时Link,出现以下错误:

错误

字符按钮.tsx

type characterButtons {
  name: string
}

const CharacterButtons: FC<characterButtons> = ({ name }) => {
  const classes = useStyles();
  return (
    <Fragment>
      <Grid
        container
        direction="row"
        justify="flex-start"
        alignItems="center"
      >
        <Link href={`https://www.example.com/character/${name}`} prefetch={false}>
          <Avatar variant="square" src={`./test.png`} className={classes.large}/>
        </Link>
      </Grid>
    </Fragment>
  )
};

export default CharacterButtons;
Run Code Online (Sandbox Code Playgroud)

据我了解,它在某种程度上与HTMLPropertyIntrinsicAttributes类型及其扩展有联系,但我不知道如何联系。另外,我找到了一些输入方法来避免以下错误,但结果是,我需要将父 FC 的每个参数传输到我的Link,例如:

<Link href={`https://www.example.com/character/${name}`} prefetch={false} ...{parent-props}>
Run Code Online (Sandbox Code Playgroud)

Ale*_*Dim 5

我在 GitHub 上的这两个片段中找到了一个解决方案,我只是在此处重新粘贴代码,但所有积分均归于:herr-vogel(next/link + MUI Button)和kachar(next/link + MUI Link 和 next/link + MUI Button) )

链接.tsx

import React, { forwardRef, Ref } from 'react'
import Link, { LinkProps } from 'next/link'
import { Link as MuiLink, LinkProps as MuiLinkProps } from '@material-ui/core'

type LinkRef = HTMLAnchorElement
type NextLinkProps = Omit<MuiLinkProps, 'href' | 'classes'> &
  Pick<LinkProps, 'href' | 'as' | 'prefetch'>

const NextLink = ({ href, as, prefetch, ...props }: LinkProps, ref: Ref<LinkRef>) => (
  <Link href={href} as={as} prefetch={prefetch} passHref>
    <MuiLink ref={ref} {...props} />
  </Link>
)

export default forwardRef<LinkRef, NextLinkProps>(NextLink)
Run Code Online (Sandbox Code Playgroud)

使用:

import Link from '../Link';
Run Code Online (Sandbox Code Playgroud)

/Linktsx 文件在哪里export default