React показывает 0 вместо ничего с условным компонентом короткого замыкания (&&)

У меня есть следующий простой оператор короткого замыкания, который должен показывать либо компонент, либо ничего:

{profileTypesLoading && <GeneralLoader />}

Если утверждение ложно, оно отображает 0 вместо ничего.

Я сделал console.info(profileTypesLoading), чтобы быстро увидеть, каков статус свойства profileTypesLoading, и он либо 1, либо 0, как и ожидалось. 0 должен быть ложным ... ничего не выводить. Верно?

Есть идеи, почему это могло произойти?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
94
0
20 203
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Это решило бы проблему:

{!!profileTypesLoading && <GeneralLoader />}

Поскольку он преобразует 0 в false. Причина в том, что когда это 0, следующее условие не выполняется, и оно ведет себя как число в JavaScript, поэтому здесь помогает двойное отрицание.

Вы также можете использовать {profileTypesLoading > 0 && <GeneralLoader />} как React docs говорит

Guilherme Samuel 07.02.2021 04:13
Ответ принят как подходящий

Поскольку ваше условие является ложным и поэтому не возвращает второй аргумент (<GeneralLoader />), оно вернет profileTypesLoading, которое является числом, поэтому react будет отображать его, потому что React пропускает рендеринг для всего, что является typeofboolean или undefined, и будет отображать все, что typeofstring или number:

Чтобы сделать его безопасным, вы можете использовать тернарное выражение {condition ? <Component /> : null} или логическое преобразование вашего условия, например {!!condition && <Component />}

Я приму это, как только мне позволят через 3 минуты ... но спасибо, это имеет смысл. Я удивлен, что этого нет ни в одном из объяснений, которые я читал по этому методу. Это всегда писалось так, как писала я. Без кастинга. Урок выучен!

Gurnzbot 29.10.2018 16:03

Вы также можете использовать оператор Boolean, если !!condition вас смущает. Что-то вроде { Boolean(condition) && <Component /> }

vijayscode 10.05.2019 08:51

таблица истинности реакции: jsfiddle.net/milahu/k2z3wocm/5

Mila Nautikus 18.08.2020 10:53

0 является ложным значением, поэтому, когда оно оценивается &&, оно возвращает 0. Однако 0 может отображаться в React, потому что это число:

// Renderable values
1 && <GeneralLoader /> // => Renders <GeneralLoader />
"a string" && <GeneralLoader /> // => Renders <GeneralLoader />
0 && <GeneralLoader /> // => Renders '0'

// Non-renderable values
false && <GeneralLoader /> // => Renders nothing
null && <GeneralLoader /> // => Renders nothing
undefined && <GeneralLoader /> // => Renders nothing

TL; DR

Это связано с тем, как сам javascript обрабатывает [значения правдивый и ложь] [1]:

In JavaScript, a truthy value is a value that is considered true when encountered in a Boolean context. All values are truthy unless they are defined as falsy (i.e., except for false, 0, "", null, undefined, and NaN).

При использовании с оператором && возвращаемое значение зависит от левого значения:

  • Если левое значение истинно, возвращается правое значение.
  • Если левое значение ложно, возвращается его значение.

Примеры:

// Truthy values
1 && "hello" // => "hello"
"a string" && "hello" // => "hello"

// Falsy values
0 && "hello" // => 0
false && "hello" // => false
null && "hello" // => null
undefined && "hello" // => undefined

Те же правила применяются к JSX, потому что это [расширение синтаксиса JavaScript] [2]. Однако проблема в том, что **

Проблема в том, что 0 является ложным значением, поэтому, когда оно оценивается &&, оно возвращает 0. Однако 0 обрабатывается React, потому что это число

// Renderable values
1 && <GeneralLoader /> // => Renders <GeneralLoader />
"a string" && <GeneralLoader /> // => Renders <GeneralLoader />
0 && <GeneralLoader /> // => Renders 0

// Non-renderable values
false && <GeneralLoader /> // => Renders nothing
null && <GeneralLoader /> // => Renders nothing
undefined && <GeneralLoader /> // => Renders nothing

Чтобы сначала оценить ложное условие, можно легко использовать константу с тернарностью. Пример:

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

export default function MyComponent({ obj }) {

  const jsxResponse = !obj.someCollecctionProperty.length ? <Button>No Action</Button> 
    : 
    <>
      <Button 
        aria-label = "more"
        aria-controls = "long-menu"
        aria-haspopup = "true" 
        variant = "contained" 
        onClick = {handleClick} 
        color = {'primary'}>
          <ThumbUpAltOutlinedIcon/>OK
      </Button>
      <Menu
        id = "long-menu"
        anchorEl = {anchorEl}
        keepMounted
        open = {open}
        onClose = {handleClose}
      >
        {obj.someCollecctionProperty.map((option) => (
          <MenuItem key = {option.id} onClick = {handleClose}>
            <Avatar variant = "square" alt = {option.name} src = {option.url}/>{option.configName}
          </MenuItem>
        ))}
      </Menu>
    </>;

  return (<div>{jsxResponse}</div>);
}

jsxResponse - это визуализированный компонент, 0 при просмотре можно избежать с помощью этого

Более простой подход:

{Boolean(profileTypesLoading) && <GeneralLoader />}

Вы можете использовать двойной удар (!!). Это возвращает логическое значение true / false для значения и не отображает 0.

{!!profileTypesLoading && <GeneralLoader/>}

Другие вопросы по теме