简体   繁体   English

React——创建只接受文本作为子道具的组件的最佳方式

[英]React -- Best Way to Create Component that only accepts Text as children prop

I created a React Component that really is just a box with some styling, and the only thing it should accept as props is a block of text.我创建了一个 React 组件,它实际上只是一个带有一些样式的框,它唯一应该接受的道具是文本块。 I want this Component (called SuggestionBox) to either accept a single string of text as props.children, or accept no children at all and accept the text as a separate prop field.我希望这个组件(称为 SuggestionBox)要么接受单个文本字符串作为 props.children,要么完全不接受子级并将文本作为单独的 prop 字段接受。

I thought about 2 approaches, but was wondering if there was a better way to do this:我考虑了两种方法,但想知道是否有更好的方法来做到这一点:

1) Pass a prop (called value ), which will be the string of text in SuggestionBox. 1) 传递一个 prop(称为value ),它将是 SuggestionBox 中的文本字符串。 Use the React.Children API to ensure no children are passed down.使用 React.Children API 确保没有孩子被传递。

<SuggestionBox value={'some value'} />

const SuggestionBox = ({children, value}) => {
    if (React.Children.count(children) > 0) throw Error()
    ...
    return (...); // Render some html along with "value" prop
}
SuggestionBox.propTypes = {
    value: PropTypes.string
};

Problem is that React.Children.count(children) returns 1 even if I don't pass any children (this is the case in the above example).问题是 React.Children.count(children) 返回 1 即使我没有传递任何孩子(在上面的例子中就是这种情况)。

2) Use React.Children.only, followed by some type checking 2) 使用 React.Children.only,然后进行一些类型检查

<SuggestionBox> String to be shown </SuggestionBox>

const SuggestionBox = ({children}) => {

    React.Children.only(children);
    if (typeof React.Children.toArray(children)[0] !== String) throw Error();

   ...

Right off the bat, this doesn't really work because React.Children.only(children) expects children to be a react component not a string of text.马上,这并没有真正起作用,因为 React.Children.only(children) 期望 children 是 react 组件而不是文本字符串。 HOWEVER , that's easy to work around.但是,这很容易解决。 My real concern is whether this is the approach I should be taking.我真正关心的是这是否是我应该采取的方法。

EDIT : As per a suggestion by Akber Iqbal, I added a PropTypes declaration to the first code snippet to show that I considered it as part of the solution.编辑:根据 Akber Iqbal 的建议,我在第一个代码片段中添加了 PropTypes 声明,以表明我将其视为解决方案的一部分。

so, use proptypes to ensure that strings are passed and then check for unwanted characters before you assign the values to your state.因此,请使用 proptypes 来确保传递字符串,然后在将值分配给您的状态之前检查不需要的字符。

relevant JS for propTypes : propTypes 的相关JS

import React from "react";
import PropTypes from "prop-types";

const Hello = ({ type, name }) => {
  return (
    <p>
      Got the prop of type:<i>{type}</i> with the value: <b>{name}</b>!
    </p>
  );
};

Hello.defaultProps = {
  name: ""
};

Hello.propTypes = {
  name: PropTypes.string
};

export default Hello;

relevant JS for checking special characters :用于检查特殊字符的相关JS

const App = () => {
  const [inputStr, setInputStr] = useState("");
  const [inputStrErr, setInputStrErr] = useState("");

  const validateStr = evnt => {
    setInputStr("");
    setInputStrErr("");
    evnt.target.value.search("<") >= 0 || evnt.target.value.search(">") >= 0
      ? setInputStrErr("invalid characters detected")
      : setInputStr(evnt.target.value);
  };

  return (
    <div>
      <input
        type="text"
        onChange={e => {
          validateStr(e);
        }}
      />
      {inputStrErr || inputStrErr.length > 0 ? 
        <p className='errorMessage'>{inputStrErr}</p>
       : (
        <Hello type="string" name={inputStr} />
      )}

      <Hello type="number" name={9} />
      <Hello type="array" name={["string1", "string2"]} />
    </div>
  );
};

working stackblitz here这里工作堆栈闪电战

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

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