Как отобразить список в реакции, когда часть данных списка больше набора данных

Я новичок в React и JSX и застрял на том, как визуализировать список элементов, учитывая, что источником данных является несколько типов данных.

Мой источник данных (призматический) возвращает массив данных всех типов, каждый из которых представляет HTML-тег, например, данные с сервера:

heading3 (h3)  
paragraph (p)  
list-item (li for ul)  
list-item (li for ul)  
list-item (li for ul)  
paragraph (p)  
o-list-item (li for ol)  
o-list-item (li for ol)  
paragraph (p)

Я хочу преобразовать это в действительный HTML, вставив возвращаемые данные.

E.g. heading3 will render <h3>heading_text</h3>

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

Моей первой попыткой было сделать что-то вроде этого:

    renderSectionText(alltextdata) {
    let texthtml = [];
    let listopen = false;
    alltextdata.map((text, index) => {
        switch (text.type) {
            case "heading3":
               //if a ul/ol started, end one (insert a closing ul/ol tag)
               if(listopen){
                    texthtml.push(</ul>)
                    listopen = false;
               }
                texthtml.push(<h3 key={index}>{text.text}</h3>);
                break;
            case "paragraph":
                if(listopen){
                    texthtml.push(</ul>)
                    listopen = false;
                }
                //if a ul/ol started, end one (insert a closing ul/ol tag)
                texthtml.push(<p key={index}>{text.text}</p>);
                break;
            case "list-item":
                //if no ul/ol started, start one (insert an opening ul/ol tag)
                if(listopen === false){
                    texthtml.push(<ul>)
                    listopen = true;
                }
                texthtml.push(<li key={index}>{text.text}</li>);
                break;

            default:
                console.log(text.type);
                return;
          }
    })
    return texthtml;
}

Но в React (AFAIK) невозможно ввести тег без закрывающего. то есть это дает мне синтаксическую ошибку JSX

            case "list-item":
                //if no ul/ol started, start one 
                if(listopen === false){
                   texthtml.push(<ul>);   //error here                       
                   listopen = true;
                }
                texthtml.push(<li key={index}>{text.text}</li>);
                break;

2 ответа

Решение

Вы правы, React и JSX просто так не работают. Когда вы создаете узел HTML, он должен включать закрывающий тег или быть самозакрывающимся.

Вместо этого, когда вы сталкиваетесь с чем-то, что должно быть <li>, начните помещать их в массив. Когда вы сталкиваетесь со следующим<li> предмет, заверните все ваши <li>в <ol> или же <ul>, а затем вставьте это в свой texthtml,

Какой-то псевдокод:

let texthtml = [];
let listItems = [];
alltextdata.forEach((ea, i) => {
  if(ea.type === "list-item"){
    listItems.push(<li key={i} >{ea.text}</li>);
  } else {
    if(listItems.length > 0){
      texthtml.push(<ul key={i} >{listItems}</ul>);
      listItems = [];
    }
    // Continue with process other non-list-items here...
  }
})

Pssst вы должны использовать forEach не map так как вы строго перебираете массив, а не отображаете его в новый массив. if-else также будет немного лучше, чем switch ИМО, потому что это поможет избежать повторения вашего кода, как у вас сейчас.

Если вы работаете со своим собственным бэкэндом, я бы хотел, чтобы ваша конечная точка успокоения достигла данных, и вы можете преобразовать / проанализировать так, как вы хотите, тогда ваш внешний интерфейс коснется вашего узла / мы будем работать с бэкэндом, чтобы получить более структурированные данные. Я не знаю, подходит ли это для вашего случая, но всякий раз, когда мне приходилось делать api, давали мне информацию, и она возвращалась противно, я говорил с моей бэкэнд-командой и был как cmon парни, или вы можете разобрать ее самостоятельно, используя ваш узел / мы сервер.

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

Иначе получайте удовольствие от разбора данных на внешнем интерфейсе Q_Q...

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

Если у кого-то есть лучшее решение, хотелось бы узнать больше об этом!~:)

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