【问题标题】:Best practices for validating inherited props in React在 React 中验证继承的 props 的最佳实践
【发布时间】:2017-04-29 12:09:10
【问题描述】:

我有一个组件 <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 应该都在 &lt;Section /&gt; 组件中验证,还是应该 &lt;Section /&gt; 只验证 colorsize 而将 title 验证留给 &lt;SectionTitle /&gt;?还是有完全不同的答案?

编辑:我确实意识到 &lt;SectionTitle /&gt; 可以直接写成 &lt;h1&gt;&lt;/h1&gt; 而不用单独的组件。我用它来说明我的观点。

【问题讨论】:

    标签: javascript validation reactjs


    【解决方案1】:

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

    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'))
    <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>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-11-07
      • 2021-06-24
      • 1970-01-01
      • 2016-07-05
      • 1970-01-01
      • 2013-01-23
      • 2014-03-25
      相关资源
      最近更新 更多