Как скрыть HTML-элемент, если JSON-ключ не существует в React

Я пытаюсь скрыть или показать элемент HTML на основе наличия ключа JSON в данных, которые я ввожу. Если ключ существует, я хотел бы показать идентификатор элемента, в который я помещаю этот объект. Если ключ не существует, я бы хотел скрыть тот же идентификатор элемента. Я использую React и не уверен, принадлежит ли он к componentDidMount или к обычной функции. Я новичок, поэтому приношу свои извинения, если я случайно пропустил важный код или пишу дрянной материал.

Мой код componentDidMount:

componentDidMount = () => {
  // Need to hide an the HTML element if the json key doesn't exist in the object
  //check the JSON object for the key "workExamples"
  if (typeof props.workItemData.workExamples === "undefined") {
    console.info("it did not find the json key");
    // Change element styling to hidden
    document.getElementById("work-examples").style.visibility = "hidden";
  } else {
    return;
  }
};

Мой HTML:

<span id = "work-examples" className = "work-examples">
  <a href = {props.workItemData.workExamples}>Work Examples</a>
</span>

Я предполагаю, что мне не нужно публиковать свои объекты JSON. У меня есть несколько; только у одного есть ключ workExamples. Я использую .map() для перечисления объектов.

С помощью приведенного выше кода он не скрывает элементы в списке для объектов JSON, у которых нет ключа. Надеюсь, все это имеет смысл. Любая помощь приветствуется.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
3
0
1 094
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Если вы просто берете опору и потенциально выводите ее, вы можете сделать ее простой и просто указать то, что вам нужно, в переменной.

render() {
  let conditionalElement = null;
  if (props.workItemData.workExamples) {
    conditionalElement = (
      <span id = "work-examples" className = "work-examples">
        <a href = {props.workItemData.workExamples}>Work Examples</a>
      </span>
    );
  }
  return (
    <div>
      {conditionalElement}
    </div>
  );
}

Это позволит вам иметь нулевое значение, которое при необходимости может быть введено в JSX (ничего не даст), затем проверьте, есть ли там свойство, а затем замените нулевое значение своим JSX.

Кроме того, да, используйте стандартный синтаксис функции componentDidMount () {}, и typeof был бы ненужным.

Ответ принят как подходящий

Как отмечает Люк в комментариях,

the logic for whether or not to render should live in render

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

Еще несколько моментов:

Вы пытаетесь использовать стрелочную функцию для определения стандартной функции React componentDidMount, и, основываясь на быстром локальном тесте, я не думаю, что React может это понять. Не похоже, что вы получаете от него какую-то особую выгоду по сравнению с традиционным синтаксисом componentDidMount() { /* do stuff here */ }, поэтому я бы переключился на последний.

Вы пытаетесь проверить, содержит ли ваш JSON ключ с

typeof props.workItemData.workExamples === "undefined"

но я не вижу необходимости в typeof; вы можете просто проверить наличие ключа напрямую:

if (props.workItemData.workExamples) { /* do stuff */ }

Наконец, в вашем HTML строка

<a href = {props.workItemData.workExamples}>Work Examples</a>

пытается установить значение href с помощью значения из JavaScript (материал в фигурных скобках). Это справедливо для JSX, что имеет смысл, поскольку вы используете React, но не в чистом HTML. Но поскольку страница загружается и просто не обрабатывает определенную часть логики правильно, я предполагаю, что вы имели в виду только HTML-подобные вещи внутри вашего JSX (файл something.js), а не буквально файл HTML.

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

Luke 07.05.2018 23:57

Ах, скучал по лесу из-за деревьев на этом. Спасибо за совет (я тоже новичок в React).

SOLO 08.05.2018 17:16
if (props.workItemData.workExamples) { /* do stuff */ } оказался тем, что мне было нужно. Я поместил это в componentDidMount, и если он обнаружил, что ключ JSON, он изменил идентификатор элемента со скрытого на видимый. Думаю, я понимаю все комментарии о том, что мне может не понадобиться весь componentDidMount, и я могу просто опустить логику внутри render? Я знаю, что недостаточно разбираюсь во всем этом, чтобы быстро и эффективно описывать вещи - мои извинения. Я учусь .... но я всем вам благодарен.
Kelly Nelson 09.05.2018 18:25

Я не думаю, что люди говорят, что вам вообще не нужен componentDidMount, это зависит от того, что еще вы там делаете. Официальная ссылка на документы: reactjs.org/docs/react-component.html#componentdidmount Насколько я понял, сообщение заключалось в том, что использование render - это «способ React» (и является является фундаментальной частью React). Даже если нет странных взаимодействий с другим кодом, вы получаете преимущество в удобстве сопровождения, поскольку другие разработчики или даже будущее - вы, вероятно, будете искать рендеринг там, а не ожидать его где-либо еще. Вы знаете, разделение забот, сплоченность и т. д.

SOLO 09.05.2018 19:23

Попробуй это

render(){
   return props.workItemData.workExamples && (
      <span id = "work-examples" className = "work-examples"> 
        <a href = {props.workItemData.workExamples}>Work Examples</a>
      </span>)
}

Код, который вы разместили, действительно не имеет никакого смысла. Вы должны прочитать о React и о том, как он работает. Вам никогда не понадобится DOM-select-by-ID для HTML-элемента, отображаемого компонентом React из этого компонента React. Вместо этого вы просто заставляете функцию рендеринга компонента React проверять ваше условие, а затем соответствующим образом отображать HTML.

За исключением того, что на самом деле здесь вы даже не можете этого делать, потому что если вы используете карту так, как я думаю (вы не публиковали свои данные, поэтому трудно сказать), вы можете просто сгенерировать HTML элемент для каждого элемента в массиве. Поэтому, если его нет в массиве, он не будет map ().

render() {
    let workItems = this.props.workItemData ? this.props.workItemData.map((item) =>
        <span id = {Object.keys(item)[0]} className = {Object.keys(item)[0]}>
            <a href = {item[Object.keys(item)[0]]}>{Object.keys(item)[0]}</a>
        </span>
    ) : '';

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

Голосование за это. Другие предлагаемые решения работают нормально, но вы фактически указываете причину, по которой метод OP не имеет никакого смысла при использовании React.

Eugen Timm 08.05.2018 08:51

Я бы удалил объекты без ключа до того, как был создан какой-либо из их соответствующих компонентов. Что-то вроде:

render() {
  return (
    <div>
      {
        Object.keys(workItems)
        .filter(item => item.workExamples)
        .map(item => <YourComponent {...item} />)
      }
    </div>
  )
}

В React я хотел отображать только существующие элементы после сопоставления, поэтому в элемент списка я добавил логику CSS:

 render() {
  return (
    <div>
      {
        data.map ((item) => {
        return (<div>

    <li>{item.answer1}</li>
    <li>{item.answer2}</li>
    <li>{item.answer3}</li>
    <li style = {{display: item.answer4 ? 'block' : 'none'}}> 
     {item.answer4}</li>
    <li style = {{display: item.answer5 ? 'block' : 'none'}}> 
     {item.answer5}</li>
    <li style = {{display: item.answer6 ? 'block' : 'none'}}> 
      {item.answer6}</li>

) ) } ) }

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