gpt4 book ai didi

reactjs - React.cloneElement & typescript

转载 作者:行者123 更新时间:2023-12-05 04:44:47 34 4
gpt4 key购买 nike

我正在尝试使用 React 和 Typescript 制作仪表板。我使用 Card 组件通过 React.cloneElement 将子组件推送到其中,并添加 Card 的 setStates 以从子组件向 Card 添加类和标题。现在添加的 setState 函数出现错误。在示例中,我删除了不必要的代码和类型以使代码更具可读性。示例:

import React, {useState} from 'react'

function App() {
return (
<div>
<Block
id="users-component"
title="Users Table"
>
<MyTable class="users" />
</Block>

<Block
id="status-component"
title="Status Component"
>
<Status class="status" /> {/* Property 'renewTitle' is missing in type '{ class: string; }' but required in type 'IStatus'. */}
</Block>

<Block
id="bdays-component"
title="Bdays Component"
>
<Bdays class="bdays" /> {/* Property 'addClasses' is missing in type '{ class: string; }' but required in type 'IBDays'. */}
</Block>
</div>

)
}

interface IBlock {
children: JSX.Element,
id: string,
title: string
}

function Block(props: IBlock) {
const [classes, addClasses] = useState<string[]>([""])
const [title, renewTitle] = useState<string>(props.title)
return (
<div id={props.id} className={classes.join(" ")}>
<h2>{props.title}</h2>
{React.cloneElement(props.children, {addClasses, renewTitle})}
</div>
)
}

function MyTable(props) {
return (
<table> </table>
)
}

interface IStatus {
class: string,
renewTitle: (title: string) => void // ?
}

function Status(props: IStatus) {
const handleClick = (title) => {
props.renewTitle(title) // changes title in Block
}
return (
<div>
<button onClick={() => handleClick("newTitle")}>New Title</button>
</div>
)
}

interface IBDays {
class: string,
addClasses: (classes: string[]) => void // ?
}



function Bdays(props: IBDays) {
const handleClick = (newClass: string) : void => {
props.addClasses([newClass]) // add new class to array "classes" in it's block
}
return (
<div className={props.class}>
<button onClick={() => handleClick("newClass")}>New Class</button>
</div>
)
}

我该如何解决这些问题?

最佳答案

更新

你需要做一个小的重构。 TypeScript 无法确定您正在克隆子组件。我改变了一点逻辑。因为允许 children属性是一个函数我只是将必需的 Prop 传递给这个函数。

现在 TS 能够算出 props内部参数 {(props) => <Status class="status" {...props} />}实际上是有效的

请看评论

import React, { useState } from 'react'

function App() {
return (
<div>
<Block
id="users-component"
title="Users Table"
>{() => <MyTable class="users" />}
</Block>

<Block
id="status-component"
title="Status Component"
>{(props) => <Status class="status" {...props} />}
</Block>

<Block
id="bdays-component"
title="Bdays Component"
>
{(props) => <Bdays class="bdays" {...props} />}

</Block>
</div>

)
}

interface IBlock {
children: (
props: {
addClasses: React.Dispatch<React.SetStateAction<string[]>>,
renewTitle: React.Dispatch<React.SetStateAction<string>>
}
) => React.ReactNode
id: string,
title: string
}

const Block: React.FC<IBlock> = (props: IBlock) => {
const [classes, addClasses] = useState<string[]>([""])
const [title, renewTitle] = useState<string>(props.title)
return (
<div id={props.id} className={classes.join(" ")}>
<h2>{props.title}</h2>
{props.children({ addClasses, renewTitle })}
</div>
)
}

function MyTable(props: { class: string }) {
return (
<table> </table>
)
}

interface IStatus {
class: string,
renewTitle: (title: string) => void
}

function Status(props: IStatus) {
const handleClick = (title: string) => {
props.renewTitle(title)
}
return (
<div>
<button onClick={() => handleClick("newTitle")}>New Title</button>
</div>
)
}

interface IBDays {
class: string,
addClasses: (classes: string[]) => void
}



function Bdays(props: IBDays) {
const handleClick = (newClass: string): void => {
props.addClasses([newClass])
}
return (
<div className={props.class}>
<button onClick={() => handleClick("newClass")}>New Class</button>
</div>
)
}

Playground

关于reactjs - React.cloneElement & typescript ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69266591/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com