[英]How to pass props from different component(about and contact)? not parent to child. Using react typescript
Im trying to reused the about component to contact component.我试图重用 about 组件来联系组件。 but i can't pass the data using props.但我无法使用道具传递数据。 when i debug it the props is undefined.当我调试它时,道具是未定义的。 and sometime the error is map undefined.有时错误是 map 未定义。
Here is my code这是我的代码
"ABOUT COMPONENT" about.tsx “关于组件” 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;
The props is undefined such as items, background, minimumHeight, justify, align, fullWidth道具未定义,例如项目、背景、最小高度、对齐、对齐、全宽
It is a parent-child relationship.这是一种父子关系。 I don't know why you think it's not.我不知道你为什么认为它不是。 ContactComponent
is the parent and AboutComponent
is the child. ContactComponent
是父组件, AboutComponent
是子组件。
ContactComponent
requires that it be called with all of the props of AboutComponent
and you are passing them down correctly. ContactComponent
要求使用AboutComponent
的所有道具调用它,并且您正确地传递它们。 If you are getting errors that the props are undefined
then that problem isn't in the code you've posted here.如果您收到道具undefined
的错误,那么该问题不在您在此处发布的代码中。 It's that you are calling <ContactComponent/>
without the right props.这是您在没有正确道具的情况下调用<ContactComponent/>
。
But there are a lot of other problems.但是还有很多其他的问题。 The most glaring one is the prop items
-- your types say that it is a string
, but your code treats it as an array
of objects with properties { heading, url, openInNewWindow, fontColor }
.最明显的是道具items
——您的类型说它是一个string
,但您的代码将其视为具有属性{ heading, url, openInNewWindow, fontColor }
的对象array
。 You need to either A) require that you have an array of these objects or B) use the children
prop and call your AboutComponent
with <Text/>
elements inside of it.您需要 A) 要求您拥有这些对象的数组或 B) 使用children
道具并在其中调用带有<Text/>
元素的AboutComponent
。
You don't want to use dangerouslySetInnerHTML
and you really don't need it.你不想使用dangerouslySetInnerHTML
的SetInnerHTML,你真的不需要它。 It doesn't do anything here unless your Text
component is taking this prop and using it.除非您的Text
组件正在使用此道具并使用它,否则它不会在这里做任何事情。 It looks like your Text
is already taking a text
prop so it can create its own HTML content.看起来您的Text
已经在使用text
道具,因此它可以创建自己的 HTML 内容。
You might want to make some of the style props optional.您可能希望将一些样式道具设为可选。 Right now they are all required.现在它们都是必需的。
This is my attempt to clean-up your components:这是我清理组件的尝试:
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>
);
};
With that sort of setup you call it like this, where items
is an array of props objects.通过这种设置,您可以这样称呼它,其中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}
/>
);
This makes sense if the data is coming in a raw form from a database or API.如果数据以原始形式来自数据库或 API,这很有意义。 But if you are writing out props yourself you probably want to call it using modular pieces:但是,如果您自己编写道具,您可能希望使用模块化部件来调用它:
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>
);
So you would make use of the children
prop rather than passing props down multiple levels.因此,您将使用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>
);
};
This code is mostly the same but we can actually delete a few of the components.这段代码基本相同,但我们实际上可以删除一些组件。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.