在React中验证继承道具的最佳实践

时间:2017-04-29 12:09:10

标签: javascript validation reactjs

我有一个组件<Section />,它包含3个道具:

  • color
  • size
  • title

虽然它使用colorsize进行某些自定义样式,但仅使用title道具,因此可以将其传递给它的孩子<SectionTitle /> ,所以我们最终得到这样的东西:

const SectionTitle = ({ title })  => (
  <h1>{title}</h1>
)

const Section = ({ color, size, title }) => ( 
  <div style={{backgroundColor: color, width: size}}>
    <SectionTitle title={title} />
    ...
  </div>
)

ReactDOM.render(<Section color='blue' size={500} title='Hello!' />, someContainerNode)

所以我想知道在这种情况下编写propTypes验证的最佳实践是什么。是colorsizetitle都应在<Section />组件中验证,还是<Section />仅验证colorsize并将title验证留给<SectionTitle />?或者是否有完全不同的答案?

编辑:我确实认识到<SectionTitle />只能以<h1></h1>的形式内联编写,而无需单独创建一个组件。我只是为了说明我的观点而使用它。

1 个答案:

答案 0 :(得分:0)

恕我直言,你不应该在SectionTitle内使用Section。你可以这样做:

&#13;
&#13;
const SectionTitle = ({ children }) => (
  <h1>{children}</h1>
);

SectionTitle.propTypes = {
  children: React.PropTypes.string.isRequired
};

const SectionContent = ({ children }) => (
  <div>{children}</div>
);

    
const Section = ({ color, size, children }) => ( 
  <div style={{backgroundColor: color, width: size}}>
    {children}
  </div>
);

Section.propTypes = {
  color: React.PropTypes.string,
  size: React.PropTypes.number,
  children: (props, propName) => {
    const prop = props[propName];
    const validElements = [SectionTitle, SectionContent];
    let error = null;

    React.Children.forEach(prop, child => {
      if(!validElements.includes(child.type)) {
        error = new Error(
          'Section accepts only <SectionTitle> and <SectionContent> as children.'
        );
      }
    });

    return error;
  }
};

ReactDOM.render(
  <Section color='#ddd' size={500}>
    <SectionTitle>some title</SectionTitle>
    <SectionContent>
      <p>some content here</p>
    </SectionContent>
  </Section>
, document.getElementById('app'))
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
&#13;
&#13;
&#13;