Реагировать на условный рендеринг происходит только частично - PullRequest
0 голосов
/ 30 мая 2020

У меня есть компонент react, который отображает результаты массива как Badge (из библиотеки Bootstrap React). В этом условии я проверяю, больше ли длина массива нуля, и визуализирую результаты с помощью функции map. Я хотел добавить дополнительный текст для отображения в условии, но по какой-то причине тег h1 не отображается, но значки отображаются. Почему не отображается тег h1 ??

render() {
   const arr = this.state.items;
   return( 
    <Card>
     <Card.Body>
      <div>
       {arr.length > 0 && <h1>Additional Text</h1> &&
        arr.map((item) => 
        <Badge key={item.toString()} pill variant='primary'>
          {item}
        </Badge>
       }
     </div>
    </Card.Body>
   </Card>
);

Ответы [ 5 ]

3 голосов
/ 30 мая 2020

Вы используете И оценку короткого замыкания , которая оценивает каждое выражение (до &&) и возвращает результат, если оно ложно, или возвращает последнее, если все другие - правдивы.

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

Для визуализации H1 также используйте два отдельных выражения:

render() {
   const arr = this.state.items;
   return( 
    <Card>
     <Card.Body>
      <div>
       {arr.length > 0 && <h1>Additional Text</h1>}
       {arr.length > 0 &&
        arr.map((item) => 
        <Badge key={item.toString()} pill variant='primary'>
          {item}
        </Badge>
       }
     </div>
    </Card.Body>
   </Card>
);

Другой вариант - переместить все условно визуализированные выражения в другую функцию и вызвать ее, когда выражение истинно:

renderBadges(arr) {
  return (
    <>
      <h1>Additional Text</h1>
      {arr.map((item) => (
        <Badge key={item.toString()} pill variant='primary'>
          {item}
        </Badge>
      )}
    </>
  );
}

render() {
   const arr = this.state.items;
   return( 
    <Card>
     <Card.Body>
      <div>
       {arr.length > 0 && this.renderBadges(arr)}
     </div>
    </Card.Body>
   </Card>
);
1 голос
/ 30 мая 2020

, потому что && проверяет его предыдущее условие или утверждение на достоверность

 render() {
 const arr = this.state.items;
 return( 
  <Card>
   <Card.Body>
    <div>
   {arr.length > 0 && <> <h1>Additional Text</h1>
    arr.map((item) => 
    <Badge key={item.toString()} pill variant='primary'>
      {item}
    </Badge>
    </>
   }
  </div>
 </Card.Body>
 </Card>
);
1 голос
/ 30 мая 2020

Попробуйте обернуть свой контент в div, поскольку у вас такое же условие, поэтому нет необходимости дублировать условие, например:

render() {
   const arr = this.state.items;
   return( 
    <Card>
     <Card.Body>
       {arr.length > 0 && (
       <div>
        <h1>Additional Text</h1>
        {arr.map((item) => 
          <Badge key={item.toString()} pill variant='primary'>
            {item}
          </Badge>
        }
       </div>)
    </Card.Body>
   </Card>
);
1 голос
/ 30 мая 2020

Это потому, что arr.length > 0 && <h1>Additional Text</h1> принимает значение true, и вы видите теги.

Более чистый подход - это сделать что-то вроде этого (просто предложение, есть много других возможных и одинаково правильных способов):

const getPills = (items) => {
    const pills = [<h1>Additional Text</h1>];
    items.forEach(item => {
        pills.push(
            <Badge key={item.toString()} pill variant='primary'>
                {item}
            </Badge>
        );
    })
    return pills;
};

render() {
   const arr = this.state.items;
   return( 
    <Card>
     <Card.Body>
      <div>
       {arr.length ? getPills(arr) : ''}
     </div>
    </Card.Body>
   </Card>
);
0 голосов
/ 30 мая 2020

Из того, что я вижу, вы пытаетесь неправильно использовать условные операторы. Из документов здесь .

expr1 && expr2 означает, что если expr1 можно преобразовать в true, возвращается expr2; else возвращает expr1.

т.е. ваше первое выражение arr.length > 0 возвращает истину, поэтому ваше второе выражение оценивается <h1>...</h1>, которое также оценивается как истина. Следовательно, последнее выражение оценивается и возвращается.

Итак, чтобы отобразить оба компонента, вы можете использовать фрагменты или, как предлагали другие, использовать несколько условных выражений или обернуть в div.

{
  arr.length > 0 && 
  <>
  <h1>Additional Text</h1>
  {
     arr.map((item) => 
        <Badge key={item.toString()} pill variant='primary'>
          {item}
        </Badge>
  }
  </>        
}

Здесь <> и </> являются сокращениями для <React.Fragment> и </React.Fragment> и дадут вам ту же древовидную структуру, которую вы, возможно, хотели бы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...