简体   繁体   English

如何在反应 typescript 中限制 props.children?

[英]How to restrict props.children in react typescript?

import React from 'react';
import './App.css';
import Message from "./components/Message";

function App() {
    return (
        <div className="App">
            <Message>
                <p>Hello World</p>
            </Message>
            <Message>
                <a>Hello World</a>
            </Message>
            <Message>
                <button>Hello World</button>
            </Message>
        </div>
    );
}

export default App;

import React, {FunctionComponent} from 'react';

interface OwnProps {
    children: React.ReactElement<HTMLParagraphElement>;
}

type Props = OwnProps;

const Message: FunctionComponent<Props> = ({children}) => {

    return (
        <h1>
            {children}
        </h1>
    );
};

export default Message;

The above code I can pass any HTMLElementTag as props.上面的代码我可以将任何 HTMLElementTag 作为道具传递。
Is there any way to restrict ReactElement to only specific element?有什么方法可以将 ReactElement 限制为仅特定元素吗? For example only with p tag or button tag etc.例如仅使用 p 标签或按钮标签等。

You can render specific children with React.Children by checking its type.您可以通过检查其类型来使用React.Children渲染特定的子项。 Below example only renders p tag elements.下面的示例仅呈现 p 标签元素。

import React, { Children } from "react";

interface Props {
  children: React.ReactElement<HTMLParagraphElement | HTMLHeadElement>[] | React.ReactElement<HTMLParagraphElement | HTMLHeadElement>;
}

const Component: React.FC<Props> = ({ children }) => {
  const elements = Children.map(children, (child) => {
    if ((child as React.ReactElement).type === "p") {
      return child;
    }
    return null;
    
  })?.filter(Boolean);

  return <div>{elements}</div>;
};

export default Component;

Note that type of custom component is a function, not string.请注意,自定义组件的类型是 function,而不是字符串。 And if you want to check types of nested html elements, you need to recursively check types of react elements children.如果你想检查嵌套的 html 元素的类型,你需要递归地检查反应元素子元素的类型。

I do not know what you are trying to do here, but there may be a better approach than restricting render of children elements.我不知道你在这里想做什么,但可能有比限制子元素渲染更好的方法。

I think this is the wrong way to be going about implementing HTMl here: if you want a <h1> element to render then you shouldn't be passing <p> or <button> elements into it.我认为这是在此处实施 HTMl 的错误方法:如果您想要呈现<h1>元素,则不应将<p><button>元素传递给它。

Why not just leave the functional component input here as just a string?为什么不将功能组件输入保留为字符串? Like so:像这样:

import React from 'react';

interface MessageProps {
    messageText: string;
}

const Message: React.FC<MessageProps> = ({ messageText }) => {

    return (
        <h1>
            {messageText}
        </h1>
    );
};

export default Message;

//////


import React from 'react';
import Message from "./components/Message";

function App() {
    return (
        <div className="App">
            <Message messageText="Hello world" />
        </div>
    );
}

export default App;


you can use following for static checking:您可以使用以下方式进行 static 检查:

type Props = { children: React.ReactNode } //-- allow any React valid Node
// type Props = { children: never } //-- will not allow children to be passed

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM