Как отобразить список в реакции, когда часть данных списка больше набора данных
Я новичок в 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:)
Если у кого-то есть лучшее решение, хотелось бы узнать больше об этом!~:)