简体   繁体   English

NextJS 动态导入问题

[英]NextJS dynamic import issue

I'm facing a really strange issue with dynamic import from NextJS .NextJS dynamic导入时,我遇到了一个非常奇怪的问题。

I'm importing a component like so:我正在导入这样的组件:

const Spinner = dynamic(() => import('components/ui/Spinner').then(mod => mod.Spinner))

And the Spinner.tsx is Spinner.tsx

import {useEffect, useState} from 'react'
import PulseLoader from 'react-spinners/PulseLoader'

import {FadeHOC} from '.'
import theme from 'utils/theme'


interface Props {
  inline?: boolean
}

const TIMEOUT = 1000

export const Spinner = ({inline}: Props) => {

  const [show, setShow] = useState(false)

  useEffect(() => {
    
    const timeout = setTimeout(
      () => setShow(true),
      TIMEOUT
    )
    
    return () => clearTimeout(timeout)
  }, [])

  return (
    show
      ? <FadeHOC>
          <PulseLoader size={10} margin={3} color={theme.color} css={inline ? 'margin-left: 14px;' : 'display: block; text-align: center; margin: 100px auto;'} />
        </FadeHOC>
      : null
  )
}

And on the dynamic import statement I get a TypeScript complaint:dynamic导入语句中,我收到了TypeScript投诉:

Argument of type '() => Promise<(({ inline }: Props) => JSX.Element) | ComponentClass<never, any> | FunctionComponent<never> | { default: ComponentType<never>; }>' is not assignable to parameter of type 'DynamicOptions<{}> | Loader<{}>'.
  Type '() => Promise<(({ inline }: Props) => JSX.Element) | ComponentClass<never, any> | FunctionComponent<never> | { default: ComponentType<never>; }>' is not assignable to type '() => LoaderComponent<{}>'.
    Type 'Promise<(({ inline }: Props) => Element) | ComponentClass<never, any> | FunctionComponent<never> | { default: ComponentType<never>; }>' is not assignable to type 'LoaderComponent<{}>'.
      Type '(({ inline }: Props) => Element) | ComponentClass<never, any> | FunctionComponent<never> | { default: ComponentType<never>; }' is not assignable to type 'ComponentType<{}> | { default: ComponentType<{}>; }'.
        Type '({ inline }: Props) => JSX.Element' is not assignable to type 'ComponentType<{}> | { default: ComponentType<{}>; }'.
          Type '({ inline }: Props) => JSX.Element' is not assignable to type 'FunctionComponent<{}>'.
            Types of parameters '__0' and 'props' are incompatible.
              Type '{ children?: ReactNode; }' has no properties in common with type 'Props'.ts(2345)

I can't figure out what the complaint is about, and I'd really appreciate any help!我不知道投诉的内容是什么,非常感谢任何帮助!

dynamic is typed like that: dynamic类型如下:

export default function dynamic<P = {}>(dynamicOptions: DynamicOptions<P> | Loader<P>, options?: DynamicOptions<P>): React.ComponentType<P>;

where P is props of the imported component其中 P 是导入组件的道具

So, dynamic expects to get Loader<P> = LoaderComponent<P> = Promise<React.ComponentType<P>因此,动态期望得到Loader<P> = LoaderComponent<P> = Promise<React.ComponentType<P>

You just need to tell him what the props are.你只需要告诉他道具是什么。 Like this:像这样:

const Spinner = dynamic<{ inline?: boolean }>(
  () => import('components/ui/Spinner').then(mod => mod.Spinner)
)

or或者

import { Spinner as StaticSpinner } from 'components/ui/Spinner'

const Spinner = dynamic<React.ComponentProps<typeof StaticSpinner>>(
  () => import('components/ui/Spinner').then(mod => mod.Spinner)
)

or make Props as exported and then:或将 Props 导出,然后:

import { Props as SpinnerProps } from 'components/ui/Spinner'

const Spinner = dynamic<SpinnerProps>(
  () => import('components/ui/Spinner').then(mod => mod.Spinner)
)

@brc-dd is right, although small explanation why it works like that: @brc-dd 是对的,虽然很少解释为什么它会这样工作:

dynamic is typed like that: dynamic类型如下:

export default function dynamic<P = {}>(dynamicOptions: DynamicOptions<P> | Loader<P>, options?: DynamicOptions<P>): React.ComponentType<P>;

So it expects you to return React.ComponentType<P> and it means:所以它希望你返回React.ComponentType<P>这意味着:

type ComponentType<P = {}> = ComponentClass<P> | FunctionComponent<P>;

and FunctionComponent is: FunctionComponent是:

interface FunctionComponent<P = {}> {
        (props: PropsWithChildren<P>, context?: any): ReactElement<any, any> | null;
        propTypes?: WeakValidationMap<P>;
        contextTypes?: ValidationMap<any>;
        defaultProps?: Partial<P>;
        displayName?: string;
    }

So you have to have props with children key.所以你必须有children钥匙的道具。 If you don't want to mess up your component interface and it's actually not accepting children then you can just type children?: never;如果你不想弄乱你的组件界面并且它实际上不接受孩子那么你可以输入children?: never; in component Props interface.在组件 Props 接口中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM