Using React to render a list within a list
I'm very very new to React, and not very experienced in web development as a whole. I'm trying use React to generate a list within a list. I've scanned many postings, and read many documents, but just can't find anything which points me in the right direction.
The basic functionality of my app is to display a list of document titles, and for each title, a number of paragraphs which match an input search string. Text within the paragraphs which matches the search string are highlighted.
So far I have managed to render the title and all the paragraphs in a single element, but I cannot see how to break down the paragraphs into a separate list under the title.
I aware that my existing code style is a bit antiquate, but it's based on the tutorials I've been following. I'm also aware that using "dangerouslySetInnerHTML" is frowned upon, but for the moment, it works.
Any help or pointers would be greatly appreciated. Below are my code, an example of the data I'm trying formatting, and an example of the required output.
Many thanks.
class FoundDoc extends React.Component {
state = {
doclist:
};
render() {
var doclist = this.state.doclist;
doclist = doclist.map(function(data){
return(
<ul id="doc-details" key={data.title}>
<li id="doc-title">{data.title}</li>
<ul id="paragraphs" key={data.passages.length}>
<li dangerouslySetInnerHTML={{__html: data.passages}} />
</ul>
</ul>
);
});
return(
<div id="doc-details">
<form id="search" onSubmit={this.handleSubmit}>
<label>Enter Search String:</label>
<input type="text" ref="srch" placeholder="Search String" required />
<button type="submit">Search</button>
</form>
<ul>{doclist}</ul>
</div>
);
}
handleSubmit = (e) => {
e.preventDefault();
var srch = this.refs.srch.value;
fetch('/api/doclist?srch=' + srch).then(function(data){
return data.json();
}).then( json => {
this.setState({
doclist: json
});
});
};
}
ReactDOM.render(<FoundDoc />, document.getElementById('doclist'));
An example of the data which I'm trying to format:
[
{
title: "Document Title 1",
paragraphs: [
"<em>String</em> 1 found in document",
"<em>String</em> 2 found in document"
]
},
{
title: "Document Title 2",
paragraphs: [
"<em>String</em> 1 found in document",
"<em>String</em> 2 found in document",
"<em>String</em> 3 found in document",
"<em>String</em> 4 found in document"
]
},
{
title: "Document Title 3",
paragraphs: [
"<em>String</em> 1 found in document",
"<em>String</em> 2 found in document",
"<em>String</em> 3 found in document"
]
}
]
The desired layout would be:
Document Title 1
a "String 1 found in document",
b "String 2 found in document"
Document Title 2
a "String 1 found in document",
b "String 2 found in document"
c "String 3 found in document"
d "String 4 found in document"
Document Title 3
a "String 1 found in document",
b "String 2 found in document"
c "String 3 found in document"
arrays reactjs list
add a comment |
I'm very very new to React, and not very experienced in web development as a whole. I'm trying use React to generate a list within a list. I've scanned many postings, and read many documents, but just can't find anything which points me in the right direction.
The basic functionality of my app is to display a list of document titles, and for each title, a number of paragraphs which match an input search string. Text within the paragraphs which matches the search string are highlighted.
So far I have managed to render the title and all the paragraphs in a single element, but I cannot see how to break down the paragraphs into a separate list under the title.
I aware that my existing code style is a bit antiquate, but it's based on the tutorials I've been following. I'm also aware that using "dangerouslySetInnerHTML" is frowned upon, but for the moment, it works.
Any help or pointers would be greatly appreciated. Below are my code, an example of the data I'm trying formatting, and an example of the required output.
Many thanks.
class FoundDoc extends React.Component {
state = {
doclist:
};
render() {
var doclist = this.state.doclist;
doclist = doclist.map(function(data){
return(
<ul id="doc-details" key={data.title}>
<li id="doc-title">{data.title}</li>
<ul id="paragraphs" key={data.passages.length}>
<li dangerouslySetInnerHTML={{__html: data.passages}} />
</ul>
</ul>
);
});
return(
<div id="doc-details">
<form id="search" onSubmit={this.handleSubmit}>
<label>Enter Search String:</label>
<input type="text" ref="srch" placeholder="Search String" required />
<button type="submit">Search</button>
</form>
<ul>{doclist}</ul>
</div>
);
}
handleSubmit = (e) => {
e.preventDefault();
var srch = this.refs.srch.value;
fetch('/api/doclist?srch=' + srch).then(function(data){
return data.json();
}).then( json => {
this.setState({
doclist: json
});
});
};
}
ReactDOM.render(<FoundDoc />, document.getElementById('doclist'));
An example of the data which I'm trying to format:
[
{
title: "Document Title 1",
paragraphs: [
"<em>String</em> 1 found in document",
"<em>String</em> 2 found in document"
]
},
{
title: "Document Title 2",
paragraphs: [
"<em>String</em> 1 found in document",
"<em>String</em> 2 found in document",
"<em>String</em> 3 found in document",
"<em>String</em> 4 found in document"
]
},
{
title: "Document Title 3",
paragraphs: [
"<em>String</em> 1 found in document",
"<em>String</em> 2 found in document",
"<em>String</em> 3 found in document"
]
}
]
The desired layout would be:
Document Title 1
a "String 1 found in document",
b "String 2 found in document"
Document Title 2
a "String 1 found in document",
b "String 2 found in document"
c "String 3 found in document"
d "String 4 found in document"
Document Title 3
a "String 1 found in document",
b "String 2 found in document"
c "String 3 found in document"
arrays reactjs list
Instead of<li dangerouslySetInnerHTML={{__html: data.passages}} />
using something like thisdata.passages.map((passage, i) => <li key={i} dangerouslySetInnerHTML={{__html: passage}} />)
perhaps? Or is that not what you intended?
– Mikroware
Nov 20 '18 at 11:26
add a comment |
I'm very very new to React, and not very experienced in web development as a whole. I'm trying use React to generate a list within a list. I've scanned many postings, and read many documents, but just can't find anything which points me in the right direction.
The basic functionality of my app is to display a list of document titles, and for each title, a number of paragraphs which match an input search string. Text within the paragraphs which matches the search string are highlighted.
So far I have managed to render the title and all the paragraphs in a single element, but I cannot see how to break down the paragraphs into a separate list under the title.
I aware that my existing code style is a bit antiquate, but it's based on the tutorials I've been following. I'm also aware that using "dangerouslySetInnerHTML" is frowned upon, but for the moment, it works.
Any help or pointers would be greatly appreciated. Below are my code, an example of the data I'm trying formatting, and an example of the required output.
Many thanks.
class FoundDoc extends React.Component {
state = {
doclist:
};
render() {
var doclist = this.state.doclist;
doclist = doclist.map(function(data){
return(
<ul id="doc-details" key={data.title}>
<li id="doc-title">{data.title}</li>
<ul id="paragraphs" key={data.passages.length}>
<li dangerouslySetInnerHTML={{__html: data.passages}} />
</ul>
</ul>
);
});
return(
<div id="doc-details">
<form id="search" onSubmit={this.handleSubmit}>
<label>Enter Search String:</label>
<input type="text" ref="srch" placeholder="Search String" required />
<button type="submit">Search</button>
</form>
<ul>{doclist}</ul>
</div>
);
}
handleSubmit = (e) => {
e.preventDefault();
var srch = this.refs.srch.value;
fetch('/api/doclist?srch=' + srch).then(function(data){
return data.json();
}).then( json => {
this.setState({
doclist: json
});
});
};
}
ReactDOM.render(<FoundDoc />, document.getElementById('doclist'));
An example of the data which I'm trying to format:
[
{
title: "Document Title 1",
paragraphs: [
"<em>String</em> 1 found in document",
"<em>String</em> 2 found in document"
]
},
{
title: "Document Title 2",
paragraphs: [
"<em>String</em> 1 found in document",
"<em>String</em> 2 found in document",
"<em>String</em> 3 found in document",
"<em>String</em> 4 found in document"
]
},
{
title: "Document Title 3",
paragraphs: [
"<em>String</em> 1 found in document",
"<em>String</em> 2 found in document",
"<em>String</em> 3 found in document"
]
}
]
The desired layout would be:
Document Title 1
a "String 1 found in document",
b "String 2 found in document"
Document Title 2
a "String 1 found in document",
b "String 2 found in document"
c "String 3 found in document"
d "String 4 found in document"
Document Title 3
a "String 1 found in document",
b "String 2 found in document"
c "String 3 found in document"
arrays reactjs list
I'm very very new to React, and not very experienced in web development as a whole. I'm trying use React to generate a list within a list. I've scanned many postings, and read many documents, but just can't find anything which points me in the right direction.
The basic functionality of my app is to display a list of document titles, and for each title, a number of paragraphs which match an input search string. Text within the paragraphs which matches the search string are highlighted.
So far I have managed to render the title and all the paragraphs in a single element, but I cannot see how to break down the paragraphs into a separate list under the title.
I aware that my existing code style is a bit antiquate, but it's based on the tutorials I've been following. I'm also aware that using "dangerouslySetInnerHTML" is frowned upon, but for the moment, it works.
Any help or pointers would be greatly appreciated. Below are my code, an example of the data I'm trying formatting, and an example of the required output.
Many thanks.
class FoundDoc extends React.Component {
state = {
doclist:
};
render() {
var doclist = this.state.doclist;
doclist = doclist.map(function(data){
return(
<ul id="doc-details" key={data.title}>
<li id="doc-title">{data.title}</li>
<ul id="paragraphs" key={data.passages.length}>
<li dangerouslySetInnerHTML={{__html: data.passages}} />
</ul>
</ul>
);
});
return(
<div id="doc-details">
<form id="search" onSubmit={this.handleSubmit}>
<label>Enter Search String:</label>
<input type="text" ref="srch" placeholder="Search String" required />
<button type="submit">Search</button>
</form>
<ul>{doclist}</ul>
</div>
);
}
handleSubmit = (e) => {
e.preventDefault();
var srch = this.refs.srch.value;
fetch('/api/doclist?srch=' + srch).then(function(data){
return data.json();
}).then( json => {
this.setState({
doclist: json
});
});
};
}
ReactDOM.render(<FoundDoc />, document.getElementById('doclist'));
An example of the data which I'm trying to format:
[
{
title: "Document Title 1",
paragraphs: [
"<em>String</em> 1 found in document",
"<em>String</em> 2 found in document"
]
},
{
title: "Document Title 2",
paragraphs: [
"<em>String</em> 1 found in document",
"<em>String</em> 2 found in document",
"<em>String</em> 3 found in document",
"<em>String</em> 4 found in document"
]
},
{
title: "Document Title 3",
paragraphs: [
"<em>String</em> 1 found in document",
"<em>String</em> 2 found in document",
"<em>String</em> 3 found in document"
]
}
]
The desired layout would be:
Document Title 1
a "String 1 found in document",
b "String 2 found in document"
Document Title 2
a "String 1 found in document",
b "String 2 found in document"
c "String 3 found in document"
d "String 4 found in document"
Document Title 3
a "String 1 found in document",
b "String 2 found in document"
c "String 3 found in document"
arrays reactjs list
arrays reactjs list
edited Nov 20 '18 at 11:08
Nguyễn Thanh Tú
4,6693827
4,6693827
asked Nov 20 '18 at 11:06
Bob DobsonBob Dobson
183
183
Instead of<li dangerouslySetInnerHTML={{__html: data.passages}} />
using something like thisdata.passages.map((passage, i) => <li key={i} dangerouslySetInnerHTML={{__html: passage}} />)
perhaps? Or is that not what you intended?
– Mikroware
Nov 20 '18 at 11:26
add a comment |
Instead of<li dangerouslySetInnerHTML={{__html: data.passages}} />
using something like thisdata.passages.map((passage, i) => <li key={i} dangerouslySetInnerHTML={{__html: passage}} />)
perhaps? Or is that not what you intended?
– Mikroware
Nov 20 '18 at 11:26
Instead of
<li dangerouslySetInnerHTML={{__html: data.passages}} />
using something like this data.passages.map((passage, i) => <li key={i} dangerouslySetInnerHTML={{__html: passage}} />)
perhaps? Or is that not what you intended?– Mikroware
Nov 20 '18 at 11:26
Instead of
<li dangerouslySetInnerHTML={{__html: data.passages}} />
using something like this data.passages.map((passage, i) => <li key={i} dangerouslySetInnerHTML={{__html: passage}} />)
perhaps? Or is that not what you intended?– Mikroware
Nov 20 '18 at 11:26
add a comment |
3 Answers
3
active
oldest
votes
In theory you could do the following:
var doclist = this.state.doclist;
doclist = doclist.map(function(data){
return(
<ul id="doc-details" key={data.title}>
<li id="doc-title">{data.title}</li>
<ul id="paragraphs">
{data.passages.map((passage, i) => { //map your passages here.
<li key={i}><p>{passage}<p/></li>
}
</ul>
</ul>
);
});
I hope you get the idea.
add a comment |
I tried to make the HTML as similar as possible to yours even though it can be written much better. This solves your problem without distracting you with the rest.
You need to take care of the keys, try using arrow functions in the maps, destructuring the doc, etc...
render() {
const docs = this.state.docs
return docs.map(function(doc) {
return (
<ul id="doc-details" key={doc.title}>
<li id="doc-title">{doc.title}</li>
<li>
<ul id="paragraphs">
{doc.passages.map(function (passage) {
return (
<li dangerouslySetInnerHTML={{__html: passage}} />
)
})}
</ul>
</li>
</ul>
)
})
}
add a comment |
Thank you all so much, the app is now working.
As you aIl suggested, I just replaced the line:
<li dangerouslySetInnerHTML={{__html: data.passages}} />
with
{data.passages.map(function (passage) {
return (
<li dangerouslySetInnerHTML={{__html: passage}} />
and it worked as planned.
I think I had been close to that on a few occasions, but just hadn't got the correct format.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53391649%2fusing-react-to-render-a-list-within-a-list%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
In theory you could do the following:
var doclist = this.state.doclist;
doclist = doclist.map(function(data){
return(
<ul id="doc-details" key={data.title}>
<li id="doc-title">{data.title}</li>
<ul id="paragraphs">
{data.passages.map((passage, i) => { //map your passages here.
<li key={i}><p>{passage}<p/></li>
}
</ul>
</ul>
);
});
I hope you get the idea.
add a comment |
In theory you could do the following:
var doclist = this.state.doclist;
doclist = doclist.map(function(data){
return(
<ul id="doc-details" key={data.title}>
<li id="doc-title">{data.title}</li>
<ul id="paragraphs">
{data.passages.map((passage, i) => { //map your passages here.
<li key={i}><p>{passage}<p/></li>
}
</ul>
</ul>
);
});
I hope you get the idea.
add a comment |
In theory you could do the following:
var doclist = this.state.doclist;
doclist = doclist.map(function(data){
return(
<ul id="doc-details" key={data.title}>
<li id="doc-title">{data.title}</li>
<ul id="paragraphs">
{data.passages.map((passage, i) => { //map your passages here.
<li key={i}><p>{passage}<p/></li>
}
</ul>
</ul>
);
});
I hope you get the idea.
In theory you could do the following:
var doclist = this.state.doclist;
doclist = doclist.map(function(data){
return(
<ul id="doc-details" key={data.title}>
<li id="doc-title">{data.title}</li>
<ul id="paragraphs">
{data.passages.map((passage, i) => { //map your passages here.
<li key={i}><p>{passage}<p/></li>
}
</ul>
</ul>
);
});
I hope you get the idea.
answered Nov 20 '18 at 11:31


vitomadiovitomadio
535110
535110
add a comment |
add a comment |
I tried to make the HTML as similar as possible to yours even though it can be written much better. This solves your problem without distracting you with the rest.
You need to take care of the keys, try using arrow functions in the maps, destructuring the doc, etc...
render() {
const docs = this.state.docs
return docs.map(function(doc) {
return (
<ul id="doc-details" key={doc.title}>
<li id="doc-title">{doc.title}</li>
<li>
<ul id="paragraphs">
{doc.passages.map(function (passage) {
return (
<li dangerouslySetInnerHTML={{__html: passage}} />
)
})}
</ul>
</li>
</ul>
)
})
}
add a comment |
I tried to make the HTML as similar as possible to yours even though it can be written much better. This solves your problem without distracting you with the rest.
You need to take care of the keys, try using arrow functions in the maps, destructuring the doc, etc...
render() {
const docs = this.state.docs
return docs.map(function(doc) {
return (
<ul id="doc-details" key={doc.title}>
<li id="doc-title">{doc.title}</li>
<li>
<ul id="paragraphs">
{doc.passages.map(function (passage) {
return (
<li dangerouslySetInnerHTML={{__html: passage}} />
)
})}
</ul>
</li>
</ul>
)
})
}
add a comment |
I tried to make the HTML as similar as possible to yours even though it can be written much better. This solves your problem without distracting you with the rest.
You need to take care of the keys, try using arrow functions in the maps, destructuring the doc, etc...
render() {
const docs = this.state.docs
return docs.map(function(doc) {
return (
<ul id="doc-details" key={doc.title}>
<li id="doc-title">{doc.title}</li>
<li>
<ul id="paragraphs">
{doc.passages.map(function (passage) {
return (
<li dangerouslySetInnerHTML={{__html: passage}} />
)
})}
</ul>
</li>
</ul>
)
})
}
I tried to make the HTML as similar as possible to yours even though it can be written much better. This solves your problem without distracting you with the rest.
You need to take care of the keys, try using arrow functions in the maps, destructuring the doc, etc...
render() {
const docs = this.state.docs
return docs.map(function(doc) {
return (
<ul id="doc-details" key={doc.title}>
<li id="doc-title">{doc.title}</li>
<li>
<ul id="paragraphs">
{doc.passages.map(function (passage) {
return (
<li dangerouslySetInnerHTML={{__html: passage}} />
)
})}
</ul>
</li>
</ul>
)
})
}
edited Nov 20 '18 at 11:41
answered Nov 20 '18 at 11:35
Stjepan GolemacStjepan Golemac
464
464
add a comment |
add a comment |
Thank you all so much, the app is now working.
As you aIl suggested, I just replaced the line:
<li dangerouslySetInnerHTML={{__html: data.passages}} />
with
{data.passages.map(function (passage) {
return (
<li dangerouslySetInnerHTML={{__html: passage}} />
and it worked as planned.
I think I had been close to that on a few occasions, but just hadn't got the correct format.
add a comment |
Thank you all so much, the app is now working.
As you aIl suggested, I just replaced the line:
<li dangerouslySetInnerHTML={{__html: data.passages}} />
with
{data.passages.map(function (passage) {
return (
<li dangerouslySetInnerHTML={{__html: passage}} />
and it worked as planned.
I think I had been close to that on a few occasions, but just hadn't got the correct format.
add a comment |
Thank you all so much, the app is now working.
As you aIl suggested, I just replaced the line:
<li dangerouslySetInnerHTML={{__html: data.passages}} />
with
{data.passages.map(function (passage) {
return (
<li dangerouslySetInnerHTML={{__html: passage}} />
and it worked as planned.
I think I had been close to that on a few occasions, but just hadn't got the correct format.
Thank you all so much, the app is now working.
As you aIl suggested, I just replaced the line:
<li dangerouslySetInnerHTML={{__html: data.passages}} />
with
{data.passages.map(function (passage) {
return (
<li dangerouslySetInnerHTML={{__html: passage}} />
and it worked as planned.
I think I had been close to that on a few occasions, but just hadn't got the correct format.
answered Nov 20 '18 at 12:14
Bob DobsonBob Dobson
183
183
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53391649%2fusing-react-to-render-a-list-within-a-list%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Instead of
<li dangerouslySetInnerHTML={{__html: data.passages}} />
using something like thisdata.passages.map((passage, i) => <li key={i} dangerouslySetInnerHTML={{__html: passage}} />)
perhaps? Or is that not what you intended?– Mikroware
Nov 20 '18 at 11:26