简体   繁体   English

如何传递来自不同组件(关于和联系)的道具? 不是父母对孩子。 使用反应 typescript

[英]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>
  );
};

Code Sandbox Link 代码沙盒链接

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.这段代码基本相同,但我们实际上可以删除一些组件。

Code Sandbox Link 代码沙盒链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用 typescript 将道具从父母传递给孩子并做出反应? - How to pass props from parent to child using typescript and react? 如何在本机反应中将道具从父组件传递到子组件? - How to pass props from parent component to child component in react native? 如何使用 React Native 中的 props 将数组从父组件传递到子组件? - How to pass an array from a parent component to child component using props in React Native? 如何将道具从子组件传递给父组件? - How to pass props from child component to parent? 将更新的状态值从父级传递给子级。 反应打字稿 - Passing an updated state value from Parent to Child. React Typescript 如何使用 react、typescript 和 styled-component 将 onclick 方法从父组件传递给子组件? - How to pass onclick method to child component from parent using react, typescript, and styled-component? 如何使用 React TypeScript 将组件传递给道具? - How to pass component to props using React TypeScript? 如何使用组合模式将 React 道具从父母传递给孩子 - How to pass React props from parent to child using composition pattern 如何在反应中将道具从父母传递给孩子? - How to pass props from parent to child in react? 在 React 中,将所有 props 从父组件传递给子组件是一个好习惯吗? - In React, is it a good practice to pass all the props from parent to child component?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM