![](/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.