I have data in for of list of lists and I want to render it in the view.
The data:
{
"blocks_content": [
[
" Bakery",
" Company GbR",
],
[
"Bill no.3-7721 11:29:51 20.04.2021"
],
[
"1x Cappuccino 2,70€ 2,70€ A"
],
]
}
I tried like this but I am not seeing any error or warning. what I could be missing?
return (
<Container>
....
{
fileBlocks !== null &&
<Form.Field>
<Label>{fileBlocks["name"]}</Label>
{fileBlocks["blocks_content"].forEach((element, index) => {
<List key={index}>
{
element.forEach((line, i) => {
<List.Item key={i}>
{line}
</List.Item>
})
}
</List>
})}
</Form.Field>
}
...
</Container>
);
use map instead of forEach .
{fileBlocks["blocks_content"].map((element, index) => (
<List key={index}>
{
element.map((line, i) => (
<List.Item key={i}>
{line}
</List.Item>
))
}
</List>
))}
Rendering Lists In React
forEach only processes arrays in place but doesn't return anything. map returns a new array of combined array information and JSX which React can use in the render.
function Example({ data }) {
return (
<div>
{data.blocks_content.map(arr => {
return (
<ul>
{arr.map((line, i) => <li key={i}>{line}</li>)}
</ul>
)
})}
</div>
);
}
const data = {
blocks_content: [
['Bakery', 'Company GbR'],
['Bill no.3-7721 11:29:51 20.04.2021'],
['1x Cappuccino 2,70€ 2,70€ A'],
]
};
// Render it
ReactDOM.render(
<Example data={data} />,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>
I make this mistake all the time! You need to use .map() instead of .forEach()
Related
i am trying to get the whole image of the img array to display but i don't know how to display the whole array . i successfully get the first element
my code
import React from "react";
const product = [
{
_id: 1,
title: "hello",
img: [
"https://product.hstatic.net/1000075078/product/hong-tra-sua-tran-chau_326977_1fbd2f506b5e4355a864260e71331a8a.jpg",
"https://product.hstatic.net/1000075078/product/1645971848_img-9789_ded484268a734fe59dd9612a8c2167c2.jpg",
"https://product.hstatic.net/1000075078/product/1645971848_hong-tra-sua-tran-chau-da-lifestyle_da3374549eec4758bf1c282804cf45e7.jpg",
],
},
];
console.log(product);
const SingleProductComponent = () => {
return (
<div>
{product.map((item, index) => {
return (
<div key={index}>
<div>
<img src={item.img[0]} />;
</div>
<div>
{item.img.map((e) => {
<img src={e.image} />;
})}
</div>
</div>
);
})}
</div>
);
};
export default SingleProductComponent;
You can use Array#map on the inner array as well. Note that you should consider using a better key than the index.
const SingleProductComponent = () => (
<div>
{product.map((item, index) => (
<div key={index}>
<div>
{item.img.map((x, _idx) => <img key={_idx} src={x} />)}
</div>
</div>
);
)}
</div>
);
{middleMenu.map((column) => {
return (
<div className="row">
column.map((item) => {
const { title, image, path } = item;
return (
<ul className="footer-collections">
<MenuLinks title={title} image={image} path={path} />
</ul>
);
})
</div>
);
})}
Does anyone know what the solution is? My first time using 2D Arrays
use :
<div className="row">
{column.map((item) => {
const { title, image, path } = item;
return (
<ul className="footer-collections">
<MenuLinks title={title} image={image} path={path} />
</ul>
);
})}
</div>
I am trying to create a reusable carousel using react-bootstrap, i could create that one"
const ReusableCarousel = (props) => {
return (
<Carousel className="mt-4 border">
{props.items.map((item, index) => {
return (
<Carousel.Item key={index}>
<Row>
{props.children}
</Row>
</Carousel.Item>
);
})}
</Carousel>
);
}
Now as you see it is reusable till the point of the carousel item, props.children may represent multiple elements per one slide or single element per slide, but i can not achieve that according to my logic
in the parent:
<ReusableCarousel items={categories}> //categories is an array of arrays of objects
{
//item prop should be passed here to carouselItemCategories component
//but i couldn't find a way to achieve that
<CarouselItemCategories key={i} />
}
</ReusableCarousel>
carouselItemCategories Component:
const CarouselItemCategories = (props) => {
//still in my dreams
const { item } = props;
return (
<>
{
item.map((c, index) => {
return (
<Col key={index}>
//a category card here
</Col>
);
})
}
</>
);
}
Now i know what makes it work, it is about passing item prop(which represent an array of objects represents fraction of my categories) but i could not find any way to achieve that
you can imagine categories like that:
const categories = [
[
{
title: 'Laptops',
background: 'red'
},
{
title: 'Tablets',
background: 'blue';
}
],
[
{
title: 'Mouses',
background: 'yellow'
},
{
title: 'Printers',
background: 'orange';
}
]
]
If I understand you correctly, you want to use each of the items from your ReusableCarousel to generate a new CarouselItemCategories with the individual item passed in as a prop?
If so, you may want to take a look at the cloneElement function. Effectively, inside your mapping of the items prop, you would create a clone of your child element, and attach the individual item as a prop to that clone. Something like this:
const ReusableCarousel = (props) => {
return (
<Carousel className="mt-4 border">
{props.items.map((item, index) => {
return (
<Carousel.Item key={index}>
<Row>
{React.cloneElement(props.children, { item })}
</Row>
</Carousel.Item>
);
})}
</Carousel>
);
}
I just found another solution by using react context, i created a CarouselContext module :
import React from 'react';
const CarouselContext = React.createContext([]);
export const CarouselProvider = CarouselContext.Provider;
export default CarouselContext
and then in the ReusableCarousel component:
import { CarouselProvider } from './carouselContext'
const ReusableCarousel = (props) => {
return (
<Carousel >
{props.items.map((item, index) => {
return (
<Carousel.Item key={index} >
<Row >
{
<CarouselProvider value={item}>
{props.children}
</CarouselProvider>
}
</Row>
</Carousel.Item>
);
})}
</Carousel>
);
}
and then using the context to get item global variable
const CarouselItemCategories = () => {
const item = useContext(CarouselContext);
return (
<>
{
item.map((c, index) => {
return (
<Col>
//category card here
</Col>
);
})
}
</>
);
}
So this is what the JSON response looks like,
and what my project is displaying
and my render looks like this:
render() {
const { materials } = this.state;
let returndata = _.isEmpty(materials) ? [] : materials
console.log('look', returndata)
return (
<div className="ui container">
<br />
<br />
<Table fixed>
<Table.Header>
<Table.Row>
<Table.HeaderCell>UUID</Table.HeaderCell>
<Table.HeaderCell>Title</Table.HeaderCell>
<Table.HeaderCell>Description</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body>
{returndata.map((item, i) => {
return (
<Table.Row key = {i}>
<Table.Cell>{item.uuid}</Table.Cell>
<Table.Cell>{item.title}</Table.Cell>
<Table.Cell>{item.description}</Table.Cell>
</Table.Row>
)
})}
</Table.Body>
</Table>
</div>
);
}
what should I do to be able to show the data(16 items) from [0] and 1 without hardcoding them, because someday I might have more arrays and not just 0 and 1.
thanks!
try this?
const aggregated = data.reduce( (agg, list) => {
return agg.concat(list.data)
}, [])
return ({aggregated.map((item, i) => Table.Row....})
Try:
<Table.Body>
{
returndata.map((item, i) => {
return (
<Table.Row key = {i}>
{
item.map(innerdata => {
return(
<Table.Cell>{innerdata.uuid}</Table.Cell>
<Table.Cell>{innerdata.title}</Table.Cell>
<Table.Cell>{innerdata.description}</Table.Cell>
)}
)}
</Table.Row>
)}
)}
</Table.Body>
The innerdata is part of an array inside the array.
I'm trying to render out a list of titles by calling map on state from inside the <MyContext.Consumer> component but the code is not returning the list items. However, if I do a console.log(dataImTryingToMap); it shows exactly what I'm trying to render. The <ul> is rendered but no <li>'s are. There are no errors thrown by create-react-app. What am I missing??? Here is the consumer component:
<MyContext.Consumer>
{context => (
<ul>
{Object.keys(context.state.subjects).map(subject => {
<li>{context.state.subjects[subject].title}</li>;
console.log(context.state.subjects[subject].title);
})}
</ul>
)}
</MyContext.Consumer>
The console log returns exactly the data I'm looking for, but nothing shows on the screen.
And here is the state from the <MyContext.MyProvider> component:
state = {
subjects: {
subject0: {
title: "Math",
description: "",
cards: {
card1: {
note: "",
answer: ""
}
}
},
subject1: {
title: "history",
description: "",
cards: {
card1: {
note: "",
answer: ""
}
}
}
}
};
Thanks for any help!
You are not returning anything from the Array.map() callback:
{Object.keys(context.state.subjects).map(subject => {
<li>{context.state.subjects[subject].title}</li>; <-- this is not returned
console.log(context.state.subjects[subject].title);
})}
const contextValue = { state: {"subjects":{"subject0":{"title":"Math","description":"","cards":{"card1":{"note":"","answer":""}}},"subject1":{"title":"history","description":"","cards":{"card1":{"note":"","answer":""}}}}}};
const MyContext = React.createContext();
const Example = () => (
<MyContext.Consumer>
{context => (
<ul>
{Object.keys(context.state.subjects).map(subject => {
console.log(context.state.subjects[subject].title);
return (
<li key={subject}>{context.state.subjects[subject].title}</li>
);
})}
</ul>
)}
</MyContext.Consumer>
);
const Demo = ({ value }) => (
<MyContext.Provider value={value}>
<Example />
</MyContext.Provider>
);
ReactDOM.render(
<Demo value={contextValue} />,
demo
);
<script crossorigin src="https://unpkg.com/react#16.3/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#16.3/umd/react-dom.development.js"></script>
<div id="demo">
</demo>
You haven't returned anything from inside the map function and hence it doesn't render anything. Either return it explicitly like
<MyContext.Consumer>
{context => (
<ul>
{Object.keys(context.state.subjects).map(subject => {
return <li>{context.state.subjects[subject].title}</li>;
})}
</ul>
)}
</MyContext.Consumer>
or implicitly like
<MyContext.Consumer>
{context => (
<ul>
{Object.keys(context.state.subjects).map(subject => (
<li>{context.state.subjects[subject].title}</li>;
))}
</ul>
)}
</MyContext.Consumer>