2016-10-11 2 views
0

Я работаю с компонентом, который отображает список словарей. Я хочу, в случае необходимости, передать опору, которая добавит дополнительный элемент списка.Как условно включить элементы списка в React Component

... 
render() { 
    return (
     <dl> 
      !! Optional !! 
      <dt>{this.props.optionalPropObj.label}</dt> 
      <dd>{this.props.optionalPropObj.value}</dd> 
      !! Optional !! 

      <dt>Label One</dt> 
      <dd>{this.props.foo.one}</dd> 

      <dt>Label Two</dt> 
      <dd>{this.props.foo.two}</dd> 

      <dt>Label Three</dt> 
      <dd>{this.props.foo.Three}</dd> 

      ... 

     </dl> 
    ); 
} 

Существует несколько способов сделать это, но я хочу свести к минимуму логический след для этого поведения. Основная проблема заключается в том, что для React нужен оберточный элемент, а <dt> и <dd> являются дочерними элементами.

Я мог бы разделить на две декларации, что является ужасно неэффективен:

... 
if (this.props.optionalPropObj) { 
    return (
     <dl> 
      // Include optional prop list element 
     </dl> 
    ); 
} else { 
    return (
     <dl> 
      // Exclude optional prop list element 
     </dl> 
    ); 
} 

Я мог бы скрыть их с классом CSS, но у меня есть 4 условными:

return (
    <dl> 
     <dt className={this.props.optionalPropObj ? '' : 'hidden'}> 
     {this.props.optionalPropObj && this.props.optionalPropObj.label} 
     </dt> 
     <dd className={this.props.optionalPropObj ? '' : 'hidden'}> 
     {this.props.optionalPropObj && this.props.optionalPropObj.value} 
     </dd> 
    </dl> 
); 

Если бы я мог обернуть элементы в div, эта ситуация была бы тривиальной.

return (
    ... 
    {includeOptional && <OptionalThing />} 
    or 
    {includeOptional ? <OptionalThing /> : null} 
    ... 
); 

В идеале, я хочу способ проверить для дополнительного реквизита раз и включают в себя дополнительный элемент без какого-либо дублирования кода.

ответ

0

Я придумал, как сделать это с действительным выходом Html. Вы условно включаете массив элементов. Поскольку единственными действительными дочерними элементами тега <dl> являются <dt> и <dd>, мне нужен способ добавления фрагмента без оболочки.

render() { 
    return (
     <dl> 
     { 
      this.props.optionalPropObj && 
      [ 
       <dt key="optionalPropLabel">{this.props.optionalPropObj.label}</dt>, 
       <dd key="optionalPropValue">{this.props.optionalPropObj.value}</dd> 
      ] 
     } 

     <dt>Label One</dt> 
     <dd>{this.props.foo.one}</dd> 

     <dt>Label Two</dt> 
     <dd>{this.props.foo.two}</dd> 

     <dt>Label Three</dt> 
     <dd>{this.props.foo.Three}</dd> 

     ... 

     </dl> 
    ); 
} 

Edit: Так как я рендеринг массива, React хочет ключи для каждого элемента, так что я добавил в некоторых фиктивных ключах. Я показываю только одно из них на странице за раз, поэтому мои требования позволяют им быть статическими.

0

Вы могли бы попробовать это

render() { 
    return (
     <dl> 
      { 
      this.props.optionalPropObj && 
      <span> 
       <dt>{this.props.optionalPropObj.label}</dt> 
       <dd>{this.props.optionalPropObj.value}</dd> 
      </span> 
      } 

      <dt>Label One</dt> 
      <dd>{this.props.foo.one}</dd> 

      <dt>Label Two</dt> 
      <dd>{this.props.foo.two}</dd> 

      <dt>Label Three</dt> 
      <dd>{this.props.foo.Three}</dd> 

      ... 

     </dl> 
    ); 
} 
+0

Да. Это то же самое, что и мой последний пример. Я хочу создать что-то вроде фрагмента документа в jsx, поэтому я только проверяю условие один раз. – Jecoms

+0

@Jecoms обновил ответ! –

+0

Я не был уверен, что это действительно html, чтобы обернуть с помощью span, но я могу согласиться на это, если мой компилятор/linter не скулит, и нет других родных опций. Было бы неплохо иметь поддержку родных фрагментов. – Jecoms

Смежные вопросы