![](/img/trans.png)
[英]How to pass props from parent to child using typescript and react?
[英]How to pass props from different component(about and contact)? not parent to child. Using react typescript
我試圖重用 about 組件來聯系組件。 但我無法使用道具傳遞數據。 當我調試它時,道具是未定義的。 有時錯誤是 map 未定義。
這是我的代碼
“關於組件” about.tsx
enum Color {
Black = 'Black',
Red = 'Red'
}
type aboutProps = {
items: string,
backgroundColor: Color,
minimumHeight: number,
justify: string,
align: string,
fullWidth: boolean
}
const AboutComponent: FC<aboutProps> = ({items, backgroundColor, minimumHeight, justify, align,
fullWidth}: aboutProps) => { return (
<>
<aboutContainer>
<div>
{items.map(({ heading, url, openInNewWindow, fontColor }) => {
return (
<Text {...props}
fontColor={fontColor}
text={heading}
url={url}
openInNewWindow={openInNewWindow}
dangerouslySetInnerHTML={{ __html: heading }}/>
)
})}
</div>
</aboutContainer>
<>
)
};
export default AboutComponent;
"CONTACT COMPONENT"
contact.tsx
interface aboutProps {
items: string,
backgroundColor: Color,
minimumHeight: number,
justify: string,
align: string,
fullWidth: boolean
}
interface contactProps extends aboutProps {
phone?: number,
name?: string,
}
const ContactComponent: FC<contactProps> = ({items, backgroundColor, minimumHeight, justify, align, fullWidth, phone, name}: contactProps) => {
return (
<>
<AboutComponent items={items}
backgroundColor = {backgroundColor}
minimumHeight = {minimumHeight}
justify = {justify}
align = {align}
fullWidth = {fullWidth}/>
</>
)
};
export default ContactComponent;
道具未定義,例如項目、背景、最小高度、對齊、對齊、全寬
這是一種父子關系。 我不知道你為什么認為它不是。 ContactComponent
是父組件, AboutComponent
是子組件。
ContactComponent
要求使用AboutComponent
的所有道具調用它,並且您正確地傳遞它們。 如果您收到道具undefined
的錯誤,那么該問題不在您在此處發布的代碼中。 這是您在沒有正確道具的情況下調用<ContactComponent/>
。
但是還有很多其他的問題。 最明顯的是道具items
——您的類型說它是一個string
,但您的代碼將其視為具有屬性{ heading, url, openInNewWindow, fontColor }
的對象array
。 您需要 A) 要求您擁有這些對象的數組或 B) 使用children
道具並在其中調用帶有<Text/>
元素的AboutComponent
。
你不想使用dangerouslySetInnerHTML
的SetInnerHTML,你真的不需要它。 除非您的Text
組件正在使用此道具並使用它,否則它不會在這里做任何事情。 看起來您的Text
已經在使用text
道具,因此它可以創建自己的 HTML 內容。
您可能希望將一些樣式道具設為可選。 現在它們都是必需的。
這是我清理組件的嘗試:
import React, { CSSProperties, FC } from "react";
export enum Color {
// CSS color names are lower-case
Black = "black",
Red = "red"
}
export type TextProps = {
text: string;
url: string;
openInNewWindow?: boolean;
fontColor?: CSSProperties["color"];
};
export const Text: FC<TextProps> = ({
text,
url,
openInNewWindow = false,
fontColor
}) => {
return (
<a
href={url}
target={openInNewWindow ? "_blank" : "_self"}
style={{ color: fontColor, display: "block", padding: 10 }}
>
{text}
</a>
);
};
export type AboutContainerProps = {
backgroundColor?: Color;
minimumHeight?: number;
justify?: string;
align?: string;
fullWidth?: boolean;
};
export const AboutContainer: FC<AboutContainerProps> = ({
backgroundColor = Color.Black,
minimumHeight,
justify = "space-evenly",
align = "center",
fullWidth = true,
children // the JSX children -- this prop is automatically included by FC
}) => {
return (
<div
style={{
background: backgroundColor,
minHeight: minimumHeight,
width: fullWidth ? "100%" : "auto",
display: "flex",
justifyContent: justify,
alignItems: align
}}
>
{children}
</div>
);
};
export type AboutProps = AboutContainerProps & {
items: TextProps[];
};
export const AboutComponent: FC<AboutProps> = ({
items,
...aboutProps // rest object for all other props
}: AboutProps) => {
return (
<AboutContainer {...aboutProps}>
{items.map((props) => {
return <Text key={props.text} {...props} />;
})}
</AboutContainer>
);
};
export type ContactInfo = {
phone?: number;
name?: string;
};
export const ContactInfoComponent: FC<ContactInfo> = ({ phone, name }) => {
if (!phone && !name) {
return null;
}
//TODO: format phone number string
return (
<div>
<h3>Get In Touch</h3>
{name && <div>{name}</div>}
{phone && <div>Call Me: {phone}</div>}
</div>
);
};
export type ContactProps = AboutProps & ContactInfo;
// do we really even need this component? can't we just compose it from the other two?
export const ContactComponent: FC<ContactProps> = ({
phone,
name,
...aboutProps
}) => {
return (
<div>
<ContactInfoComponent phone={phone} name={name} />
<AboutComponent {...aboutProps} />
</div>
);
};
通過這種設置,您可以這樣稱呼它,其中items
是 props 對象的數組。
const Test = () => (
<ContactComponent
minimumHeight={100}
justify="flex-end"
align="center"
items={[
{
text: "Home",
url: "/"
},
{
text: "Facebook",
url: "some link",
openInNewWindow: true,
fontColor: Color.Red
}
]}
name={"My Name"}
phone={5555555555}
/>
);
如果數據以原始形式來自數據庫或 API,這很有意義。 但是,如果您自己編寫道具,您可能希望使用模塊化部件來調用它:
const Test = () => (
<div>
<ContactInfoComponent name={"My Name"} phone={5555555555} />
<AboutContainer
minimumHeight={100}
justify="flex-end"
align="center"
fullWidth={false}
>
<Text url="/">Home</Text>
<Text url="some link" openInNewWindow={true} fontColor={Color.Red}>
Facebook
</Text>
</AboutContainer>
</div>
);
因此,您將使用children
道具,而不是將道具向下傳遞多個級別。
import React, { CSSProperties, FC } from "react";
export enum Color {
// CSS color names are lower-case
Black = "black",
Red = "red"
}
export type TextProps = {
url: string;
openInNewWindow?: boolean;
fontColor?: CSSProperties["color"];
};
export const Text: FC<TextProps> = ({
children,
url,
openInNewWindow = false,
fontColor
}) => {
return (
<a
href={url}
target={openInNewWindow ? "_blank" : "_self"}
style={{ color: fontColor, display: "block", padding: 10 }}
>
{children}
</a>
);
};
export type AboutContainerProps = {
backgroundColor?: Color;
minimumHeight?: number;
justify?: string;
align?: string;
fullWidth?: boolean;
};
export const AboutContainer: FC<AboutContainerProps> = ({
backgroundColor = Color.Black,
minimumHeight,
justify = "space-evenly",
align = "center",
fullWidth = true,
children // the JSX children -- this prop is automatically included by FC
}) => {
return (
<div
style={{
background: backgroundColor,
minHeight: minimumHeight,
width: fullWidth ? "100%" : "auto",
display: "flex",
justifyContent: justify,
alignItems: align
}}
>
{children}
</div>
);
};
export type ContactInfo = {
phone?: number;
name?: string;
};
export const ContactInfoComponent: FC<ContactInfo> = ({ phone, name }) => {
if (!phone && !name) {
return null;
}
//TODO: format phone number string
return (
<div>
<h3>Get In Touch</h3>
{name && <div>{name}</div>}
{phone && <div>Call Me: {phone}</div>}
</div>
);
};
這段代碼基本相同,但我們實際上可以刪除一些組件。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.