简体   繁体   English

如何仅在具有 Typescript 的容器组件的上下文中使用 React 道具?

[英]How do I make a React prop only required when used in the context of a Container component with Typescript?

I've been trying to fix this Typescript error I'm getting for some time now.我一直在尝试修复这个 Typescript 错误,我已经有一段时间了。

I've created a sandbox to illustrate the problem.我创建了一个沙箱来说明这个问题。 We have我们有

  1. An App component (this wraps everything)一个App组件(这包含了所有内容)
  2. A 'wrapper' component ( AddDateContainer ) - this renders it's children and renders either a timestamp string next to each child or the year depending on whether the child has a yearOnly prop passed to it一个“包装器”组件( AddDateContainer ) - 这会呈现它的孩子并呈现每个孩子旁边的时间戳字符串或年份,具体取决于孩子是否有传递给它的yearOnly道具
  3. A Text component - this is a super dumb component that simply renders the textToRender prop passed to it一个Text组件 - 这是一个超级愚蠢的组件,它只是呈现传递给它的textToRender道具

The problem I am getting is that Typescript is complaining about me sending a yearOnly prop to the Text component because it is not included in Text 's interface.我遇到的问题是 Typescript 抱怨我向Text组件发送yearOnly道具,因为它不包含在Text的界面中。 I'd rather not include it in Text 's interface since it only going to be seen when used within the AddDateContainer component.我宁愿不将它包含在Text的界面中,因为它只会在AddDateContainer组件中使用时才能看到。

How can I tell typescript to ignore the yearOnly prop in this case?在这种情况下,我如何告诉 typescript 忽略yearOnly道具?

this example is pretty arbitrary.这个例子很随意。 I have created this for illustration purposes.我为了说明目的而创建了这个。 The real use case is a lot more valid真正的用例更有效

Code,代码,

import React from "react";

interface TextInterface {
  textToRender: string;
}

const Text = ({ textToRender }: TextInterface) => {
  return <span>{textToRender}</span>;
};

const AddDateContainer = ({
  children
}: {
  children: React.ReactElement | React.ReactElement[];
}) => {
  const renderDate = (yearOnly: boolean) => {
    const date = new Date();
    const dateToRender = yearOnly ? date.getFullYear() : date.getTime();
    return <span>{dateToRender}</span>;
  };

  return (
    <div>
      {React.Children.map(children, (child) => {
        /**
         * IMPORTANT
         * HERE WE ARE REMOVING THE yearOnly prop because it was only needed
         * for the Container.
         * How can we get Typescript to stop complaining!?
         */
        const { format, ...originalProps } = child?.props;
        return (
          <span>
            {React.cloneElement(child, originalProps)}{" "}
            {renderDate(child.props.yearOnly)}
          </span>
        );
      })}
    </div>
  );
};

export default function App() {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <AddDateContainer>
        <Text yearOnly textToRender="I love this" />
      </AddDateContainer>
    </div>
  );
}

Is there a reason you can't add the prop to the higher order component?有没有理由不能将道具添加到高阶组件? Something like this:像这样的东西:

interface TextInterface {
  textToRender: string;
}

const Text = ({ textToRender }: TextInterface) => <span>{textToRender}</span>;

interface AddDateHocProps extends PropsWithChildren<{}> {
  readonly yearOnly: boolean;
}

const AddDateHoc = ({ children, yearOnly }: AddDateHocProps) => {
  const date = new Date();
  const dateToRender = yearOnly ? date.getFullYear() : date.getTime();

  return (
    <div>
      {React.Children.map(children, (child) => (
        <span>
          {child}
          <span>{dateToRender}</span>;
        </span>
      ))}
    </div>
  );
};

export default function App() {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <AddDateHoc yearOnly>
        <Text textToRender="I love this" />
      </AddDateHoc>
    </div>
  );
}

What you want is not functionally distinct from this:您想要的在功能上与此没有区别:

import React from "react";

interface TextInterface {
  textToRender: string;
}

const Text = ({ textToRender }: TextInterface) => {
  return <span>{textToRender}</span>;
};

const FormattedDate = ({
  yearOnly
}) => {
    const date = new Date();
    const dateToRender = yearOnly ? date.getFullYear() : date.getTime();
    return <span>{dateToRender}</span>;
};

export default function App() {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <Text yearOnly textToRender="I love this" />
      <FormattedDate yearOnly />
    </div>
  );
}

Hi guys thanks for the response.大家好,感谢您的回复。 I've found something which isn't quite what I wanted but is flexible enough that I think I'm happy with it.我发现了一些不是我想要的但足够灵活的东西,我认为我对它很满意。 I've used a generic in the Text interface.我在 Text 界面中使用了泛型。 It feels like what I was trying to do ie make the Container component handle the types might not be possible.感觉就像我试图做的,即让容器组件处理类型可能是不可能的。

Here is the change,这里是变化,

interface TextInterface {
  textToRender: string;
}

const Text = <T extends TextInterface>(props: T) => {
  const { textToRender } = props;
  return <span>{textToRender}</span>;
};

The T makes it so the yearOnly can get through (any other props I might want to add for the benefit of the Container) will get through without me explicitly writing those props into the interface. T使得yearOnly可以通过(我可能想为容器的利益添加的任何其他道具)将通过,而无需我将这些道具明确写入界面。

暂无
暂无

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

相关问题 如何在 React 和 Typescript 中将组件作为道具传递? - How do I pass a component as a prop in React and Typescript? 你如何在反应 typescript 中根据需要标记道具? - How do you mark a prop as required in react typescript? 如何在父项更改时将道具传递给反应组件但不更新子项中的该道具? - How do I pass a prop to a react component yet not update that prop in the child when parent changes? 如何将 ReactNode 定义为打字稿反应组件的道具? - How to Define ReactNode as a prop for a typescript react component? 如何在组件(React + TypeScript)中输入链接属性? - How to type link prop in component (React + TypeScript)? 我如何解析“ useHref() 只能在上下文中使用<router>组件”当组件已经在里面时<router> ?</router></router> - How can I resolver " useHref() may be used only in the context of a <Router> component" when component is already inside <Router>? TypeScript 错误 7053 - 创建一个使用 prop 覆盖样式的自定义 React 组件,我如何正确告诉 TS 类型是什么? - TypeScript Error 7053 - Creating a custom React component that overrides styles with a prop, how do I properly tell TS what the type is? 如何使用 Material UI 中的 sx prop 仅在组件被选中时实现样式? - How do I use the sx prop in material UI to implement styling only when the component is selected? 我如何判断一个 prop 是否在 react 组件中传递 - How do I tell if a prop was passed in a react component 如何在 React 中将 const 变量作为道具传递给组件? - How do I pass a const variable to a component as a prop in React?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM