Присвоить значение переменной в JSX для ReactJS

{props.stories.map((story) =>
    <div key={story.id}>
        {story = story.story}
        <SliderItem story={story} />
    </div>
)}

Приведенный выше код выдает ошибку:

Uncaught (в обещании) Ошибка: объекты недействительны в качестве дочернего элемента React (найдено: объект с ключами

потому что story в строке номер 3 является объектом.

Я могу переместить это условие напрямую как <SliderItem story={story.story} />, но я хочу знать, есть ли способ присвоить вычисленное значение переменной и использовать его в JSX?

Я хочу применить некоторую логику, например:

{ let storyObj = story.type === 'story' && story.story ? story.story : story }

person Asim K T    schedule 05.10.2017    source источник


Ответы (6)


Все, что находится между {} в JSX, — это просто JavaScript, поэтому вы можете сделать следующее:

{props.stories.map((story) => {
  const storyObj = (story.type === 'story' && story.story) ? story.story : story;
  return (
    <div key={story.id}>
      <SliderItem story={storyObj} />
    </div>
  );
})}
person Tholle    schedule 05.10.2017
comment
Я думаю, что общее желание здесь состоит в том, чтобы иметь нормальное объявление переменной внутри jsx, когда у вас нет чего-то вроде вызова .map, создающего такую ​​​​возможность. - person Devin Rhode; 22.11.2019
comment
@DevinGRhode - с одной стороны, согласен. С другой стороны, я вижу только две возможности: а) вы хотите создать выражение на основе существующих переменных JS, и в этом случае существует существует контекст JS, определяющий эту переменную. Единственная причина, по которой у OP возникли проблемы, заключается в том, что они использовали короткую форму возвращаемого значения maps, в которой отсутствовало явное {...}. Исправление заключалось в преобразовании в длинную форму. б) Вы определяете буквальное значение, и в этом случае любой объемлющий контекст JS работает нормально. РЕЗУЛЬТАТ: добавление объявления в самый тесный окружающий контекст JS всегда является доступным решением. - person ToolmakerSteve; 20.10.2020

Вы можете создать функцию вне render(), которая получит правильное значение:

function getStory(storyObj) {
  return storyObj.type === 'story' && storyObj.story ? storyObj.story : storyObj;
}

А затем используйте его в JSX:

{props.stories.map(storyObj =>
  <div key={storyObj.id}>
     <SliderItem story={getStory(storyObj)} />
  </div>
)}
person dominik791    schedule 05.10.2017
comment
Самое чистое предложение здесь. - person Chase DeAnda; 05.10.2017

Хотя я бы не рекомендовал это, поскольку это действительно запутывает ваш код, вы можете использовать оператор запятой, чтобы позволить вам присвоить значение:

{story = story.story, <SliderItem story={story} />}

Однако я не уверен, почему вы хотите это сделать?

person Develer    schedule 05.10.2017
comment
Обратите внимание, что это не позволит вам создать/объявить новую переменную. Таким образом, такие вещи, как следующее, не будут работать: {let foo = 123, <Bar foo={foo} />} - person Qtax; 12.06.2020

Я думаю, что это было бы довольно элегантным решением:

function someReactFunctionalComponent(props) {
  const vars = {}

  return (
    <div>
      <h1>... lots of code ...</h1>
      {vars.someFoo_s = bar ? dance : undefined}
      <ul>
        {
          vars.someFoo=normalizeFoo(vars.someFoo_s),
          vars.someFoo_s.map((aFoo) => (
            <li>{aFoo}</li>
          ))
        }
      </ul>
    </div>
  )
}
person Devin Rhode    schedule 21.10.2020

Почему бы тебе просто не передать story.story??

  {props.stories.map((story) =>
    <div key={story.id}>
      <SliderItem story={story.story} fallback={story} />
    </div>
  )}

В вашем компоненте, если this.props.story равно undefined, используйте this.props.fallback.

person Chase DeAnda    schedule 05.10.2017
comment
Нет. Мой компонент должен принимать обе структуры. Я не хочу, чтобы мои конечные пользователи передавали оба реквизита. Возможно, я не тот человек, который использует этот компонент. И допустим, SliderItem принимает только story - person Asim K T; 09.10.2017

Вы можете использовать IIFE (немедленно вызываемое функциональное выражение)

{props.stories.map((story) =>
    <div key={story.id}>
        {(() =>  {
          story = story.story
          return <SliderItem story={story} />
        })()}
    </div>
)}
person KMA Badshah    schedule 18.03.2021