如何在 Next.JS 13 中将 props 传递给子组件

问题描述 投票:0回答:1

我在让 NextJS 使用 props 并通过组件传递它们时遇到一些问题。这可能更像是一种 React 方法,所以也许它在这里不起作用,但我尝试过谷歌搜索,但没有多少结果返回如何做到这一点。 基本上我想做的就是简单地将 useState 和 setUseState 值从我的父级传递给子级,以便在子级 onClick 内部进行更新。

但是,当我传递 props 时,Prop 类型似乎发生了一个错误。避免它的唯一方法似乎是使用

(props: any)
但是我不想这样做,因为它不是类型安全的。

我想要在 NextJS 中做的事情是否可行,或者是否有其他方法可以做到?我查看了

getInitial/Static/ServerProps
,但也无法让它们工作。

诚然,我对 Next 没有太多经验,所以也许这是一个技能问题。

希望这足够清楚,很高兴添加更多细节,我可能错过了一些重要的东西,它一直困扰着我一整天!

感谢您的帮助。

父组件

'use client';
import { useState } from 'react';
import ChildComponent from './childComponent/page';

export default function ParentComponent() {
  const [value, setValue] = useState('hello world')
  return <ChildComponent value={value} setValue={setValue}/>
}

子组件

import React, { Dispatch, SetStateAction } from 'react'

interface Props {
  value: string
  setValue: Dispatch<SetStateAction<string>>
}

const ChildComponent = (props: Props) => {
  return (
    <div>
      <span onClick={() => props.setValue('hello moon')}>{props.value}</span>
    </div>
  )
}

export default ChildComponent

错误

.next/types/app/childComponent/page.ts:26:13
Type error: Type 'OmitWithTag<Props, keyof PageProps, "default">' does not satisfy the constraint '{ [x: string]: never; }'.
  Property 'value' is incompatible with index signature.
    Type 'string' is not assignable to type 'never'.

  24 | 
  25 | // Check the prop type of the entry function
> 26 | checkFields<Diff<PageProps, FirstArg<TEntry['default']>, 'default'>>()
     |             ^

布局.tsx

import ...

const inter = Inter({ subsets: ['latin'] })

export const metadata: Metadata = {
  title: 'Title',
  description: 'Generated by create next app',
}

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en" className=' bg-pink-300 h-screen w-screen content-center justify-center items-center flex'>
      <body className={`${inter.className} h-screen w-screen justify-center items-center flex`}>
      
        {children}
      
      </body>
    </html>
  )
}

next.config.js 是默认的

我尝试过

const Component = (props: Props)
、const
Component: React.FC<Props> = (props)
Interface/Type { value: any, setValue: any }
以及这些的所有排列都无济于事。

当运行 npm run dev 时,该应用程序也可以完美构建,并且可以更新 usestate,但是当运行 npm run build 时,它会失败。

据我所知,看起来唯一可以传递的类型是那些在索引接口中有效的类型

An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type.

interface Props {
  [key: string | number ]: string
}

因此,我现在将其保留为(道具:任意)......

编辑2:

尝试使用 Sachin 提到的组件文件夹,它工作得很好。也许你也可以用其他方式做到这一点,但我的大脑太小,或者这是不可能的。

这是类和目录布局,供任何人将来参考...

家长

'use client';
import { useState } from 'react'
import { ChildComponent } from '@/components/';
 
export default function Page() {
  const [value, setValue] = useState('hello world')
  return <ChildComponent setValue={setValue} value={value} />
}
import React, { Dispatch, SetStateAction } from 'react'

interface Props {
  value: string
  setValue: Dispatch<SetStateAction<string>>
}

const ChildComponent = (props: Props) => {
  return (
    <div>
      <span onClick={() => props.setValue('hello moon')}>{props.value}</span>
    </div>
  )
}

export default ChildComponent

谢谢大家!

reactjs next.js react-hooks react-props
1个回答
0
投票

解决方案:

使用组件文件夹,目录布局应该是这样的

root
|
├- app
|  ├ page.tsx
|  ├ layout.tsx
|  └ ...
|
├- components
|  ├ childComponent
|  | └ ChildComponent.tsx
|  └ index.ts (optional)
└ ...

Page.tsx 它应该简单地是:

'use client';
import { useState } from 'react'
import { ChildComponent } from '@/components/';
 
export default function Page() {
  const [value, setValue] = useState('hello world')
  return <ChildComponent setValue={setValue} value={value} />
}

ChildComponent.tsx(带道具):

import React, { Dispatch, SetStateAction } from 'react'

interface Props {
  value: string
  setValue: Dispatch<SetStateAction<string>>
}

const ChildComponent = (props: Props) => {
  return (
    <div>
      <span onClick={() => props.setValue('hello moon')}>{props.value}</span>
    </div>
  )
}

export default ChildComponent

如果需要,请参阅我原来的问题以获取更多详细信息!

© www.soinside.com 2019 - 2024. All rights reserved.