I'm trying to map over a map in JSX but the second inner map doesn't render why?
{food.map((item: ItemsShape, index: number) => {
return (
<div key={`${index}`}>
<div>{item.Quantity}</div>
<div>{item.Name}</div>
{item.Options && <div>{JSON.stringify(item.Options)}</div>} // <= this shows al the options
{item.Options &&
item.Options.map((option: any) => {
<div>OPTION {option.Name}</div>;
})} // <= This doesnt even render why?
</div>
);
})}
You missed return
{food.map((item: ItemsShape, index: number) => {
return (
<div key={`${index}`}>
<div>{item.Quantity}</div>
<div>{item.Name}</div>
{item.Options && <div>{JSON.stringify(item.Options)}</div>} // <= this shows al the options
{item.Options &&
item.Options.map((option: any) => {
return (<div>OPTION {option.Name}</div>);
})}
</div>
);
})}
Related
I can't find an answer in "many similar questions", sorry I'm new to react.
I have the following code inside return of my sfc that works/renders fine:
{data && allToDos && completed === 'all' && data.map(data => {
key++;
return (
<div key={key}>
<h2>{data.title}</h2>
<p className="apart">
Nr: {data.id} <span>Status: {!data.completed && <span>Not </span>}completed</span>
</p>
<h3>User: {data.userId}</h3>
<br/><hr/><br/>
</div>
);
});}
Now, I have 3 different options for completed and in each case i want to render different set of data, so i have isolated the data.map(data => {/*code*/}) into a separate function inside the same component,like that:
const dataMap = () => {
data.map(data => {
key++;
return (
<div key={key}>
<h2>{data.title}</h2>
<p className="apart">
Nr: {data.id} <span>Status: {!data.completed && <span>Not </span>}completed</span>
</p>
<h3>User: {data.userId}</h3>
<br/><hr/><br/>
</div>
);
});
}
and then i passed that function inside return like that:
{data && allToDos && completed === 'all' && dataMap()}
and nothing is rendered, but no error messages either.
You're not returning from dataMap() function it returns undefined .
try this
const dataMap = () => {
return data.map(data => {
key++;
return (
<div key={key}>
<h2>{data.title}</h2>
<p className="apart">
Nr: {data.id} <span>Status: {!data.completed && <span>Not </span>}completed</span>
</p>
<h3>User: {data.userId}</h3>
<br/><hr/><br/>
</div>
);
});
}
Getting object is possibly 'undefined' on order.reduce line.
Trying to print sum of all the amounts after printing all the amount.
<div>
{orders.map(({ id, totalAmount }) => {
return (
<div key={id}>
<div>{totalAmount}</div>
</div>
)
})}
Total: {
orders.reduce(
(t, k) => (t + k.totalAmount),
0
)
}
</div>
That is happening because TypeScript thinks the array orders array can be undefined. To fix this, you can make a check like this
const Component = () => {
return (
<div>
{orders && (
<div>
{orders.map(({ id, totalAmount }) => {
return (
<div key={id}>
<div>{totalAmount}</div>
</div>
);
})}
Total: {orders.reduce((t, k) => t + k?.totalAmount, 0)}
</div>
)}
</div>
);
};
I just can't figure out the syntax mistake here, but my React components won't render. What am I doing wrong?
return (
shouldShow && (
<div>
{this.props.photos.map(({ url }) => {
return (
this.state.expanded
? <ImageGallery passedProp={url} />
: <AnotherComponent passedProp={url}
)
})}
</div>
)
);
I get the error:
JSX attributes must only be assigned a non-empty expression
EDIT updated full code as requested:
showGallery = () => {
const shouldShow = this.props.photos.length > 0;
return (
shouldShow && (
<div>
{this.props.photos.map(({ url }) => {
return (
this.state.expandedThumbnail
? <ImageGallery imageUrl={urlurlurl}/>
: <button
key={url}
onClick={this.doThis}
>
<img
src={url}
/>
</button>
)
})}
</div>
)
);
};
Project based on Typescript vs ReactJS.
This is render code :
return (
<div ref={this.myRef} style={this.state.myStyle} >
{this.state.sections.map((sectionsItem: AppI.SectionI) => {
if (this.state.activeSection === sectionsItem.name) {
console.log("TEST :", sectionsItem.elements );
sectionsItem.elements.map((element: React.ReactElement<any>, index: number) => {
return <span key={index} >{element}</span>;
});
}
})}
</div>
);
In debugger I can see that 'elements' are not empty but it doesn't render in html.
Any suggestion ?!
You need an extra return statement:
Change: sectionsItem.elements.map to return sectionsItem.elements.map:
Your inner .map returns elements but the outer .map has no return statement:
return (
<div ref={this.myRef} style={this.state.myStyle} >
{this.state.sections.map((sectionsItem: AppI.SectionI) => {
if (this.state.activeSection === sectionsItem.name) {
console.log("TEST :", sectionsItem.elements );
return sectionsItem.elements.map((element: React.ReactElement<any>, index: number) => {
return <span key={index} >{element}</span>;
});
}
})}
</div>
);
I'm building a React component that shows a filtered list of items in a div when users click on a button. Only the items within that div should be displayed on click. For some reason, though, the lists for every section are being toggled.
What am I doing wrong?
Here is my code: https://codesandbox.io/s/6yr0jzlpwn
Simply you can just define a specific value for each button then pass it to state
<div>
<h1>{this.state.title}</h1>
<div>
<button value={'1'} onClick={this.toggleWords}>肉</button>
{this.state.showWords === '1' && (
<ul>
{this.state.list.filter(function(word) {
return word[1] === "肉";
}).map(function (word) {
return <li>{word}</li>;
})}
</ul>
)}
</div>
<div>
<button value={'2'} onClick={this.toggleWords}>茶</button>
{this.state.showWords === '2' && (
<ul>
{this.state.list.filter(function(word) {
return word[1] === "茶";
}).map(function(word) {
return <li>{word}</li>;
})}
</ul>
)}
</div>
<div>
<button value={'3'} onClick={this.toggleWords}>日</button>
{this.state.showWords === '3' && (
<ul>
{this.state.list.filter(function(word) {
return word[0] === "日";
}).map(function(word) {
return <li>{word}</li>;
})}
</ul>
)}
</div>
</div>
In toggleWords function
toggleWords(e) {
const clickedButton = e.target.value;
if(clickedButton !== this.state.showWords){
this.setState({ showWords: clickedButton })
}else{
this.setState({ showWords: '' }) // handle close list if double click
}
}
In case if you want to expand two sections at once you need to change showWords state to be an array then use indexOf method to extend the section
<div>
<h1>{this.state.title}</h1>
<div>
<button value={'1'} onClick={this.toggleWords}>肉</button>
{this.state.showWords.indexOf('1') !== -1 && (
<ul>
{this.state.list.filter(function (word) {
return word[1] === "肉";
}).map(function (word) {
return <li>{word}</li>;
})}
</ul>
)}
</div>
<div>
<button value={'2'} onClick={this.toggleWords}>茶</button>
{this.state.showWords.indexOf('2') !== -1 && (
<ul>
{this.state.list.filter(function (word) {
return word[1] === "茶";
}).map(function (word) {
return <li>{word}</li>;
})}
</ul>
)}
</div>
<div>
<button value={'3'} onClick={this.toggleWords}>日</button>
{this.state.showWords.indexOf('3') !== -1 && (
<ul>
{this.state.list.filter(function (word) {
return word[0] === "日";
}).map(function (word) {
return <li>{word}</li>;
})}
</ul>
)}
</div>
</div>
Then in toggleWords function will delete the value from array if exist else it will add it
toggleWords(e) {
const clickedButton = e.target.value;
if (this.state.showWords.indexOf(clickedButton) !== -1) { // deleting the value from array if exist
this.setState(prevState => ({ showWords: this.state.showWords.filter(d => d !== clickedButton) }))
} else {
this.setState(prevState => ({ showWords: [...prevState.showWords, clickedButton] }))
}
}