How to repeat one element in JSX? - javascript

I want repeat one image element in JSX, my required code is like as below:
<View>
<Image source={require('../images/image.png')} />
<Image source={require('../images/image.png')} />
<Image source={require('../images/image.png')} />
<Image source={require('../images/image.png')} />
<Image source={require('../images/image.png')} />
</View>
How i can use a loop to generate this code?

Easy! You can create an array on the fly. Like this:
<View>
{[...Array(5)].map((x, i) => <Image key={i} source={require('../images/image.png')} />)}
</View>
The [...Array(5)] gives: [undefined, undefined, undefined, undefined, undefined]. Which might look useless, but actually, this gives us something to iterate over with map() which we can use to return the Components we want (we don't need x here at all).
You could, to improve performance, create the array outside your render to prevent re-creating the temporary array on each re-render. You can also put your require separately for similar reasons.

You can store it in a variable before you return your jsx.
Example:
const myjsx = [];
for(let i = 0; i < 4; i++) {
myjsx.push(<Image source={require('../images/image.png')} />);
}
then in your final JSX you simply print out the {myjsx}
<View>
{myjsx}
</View>

You can create a short function to do this for you
let func = () => (<Image source={require('../images/image.png')} />)
<View>
{func()}
{func()}
{func()}
{func()}
{func()}
</View>
You can add a loop or perform additional refactorings from there.

Try this:
const totalImages = 10;
<View>
{
(new Array(totalImages)).fill(<Image source={require('../images/image.png')}/>)
}
</View>

You can create a function that loops and returns the elements in question.
renderImages() {
var images = [];
for (var i = 0; i < numrows; i++) {
images.push(<Image source={require('../images/image.png')} />);
}
return images;
}
In the render method you would just call the function name as such:
{renderImages()}

<View>
{() => {
const
longArray = new Array(7),
image = require('../images/image.png');
return longArray.map((k, i) => <Image key={k} source={image} />);
}}
</View>

Related

How do I properly use the map function to get the index of the element in the array? [duplicate]

This question already has an answer here:
ESCMAScript 6 arrow functions - parentheses around parameter
(1 answer)
Closed 10 months ago.
Hello I am trying to find the index of the element in an array using map so that eventually I can create a onClick function that will change the image based on that index.
However when I add index to my map function I then get an error stating that the img is not defined.
const currentIndex = 0;
const gallery =
product.images.length > 1 ? (
<Grid gap={2} columns={5}>
{product.images.map(img, index => (
<GatsbyImage
image={img.gatsbyImageData}
key={img.id}
alt={product.title}
/>
))}
</Grid>
) : null;
The above code displays a list of thumbnail size images. I would like to eventually be able to click on each image and have the larger image appear.
Code for the larger image is below.
<div>
<GatsbyImage
image={product.images[currentIndex].gatsbyImageData}
alt={product.title}
/>
{gallery}
</div>
Simple parenthesis fix:
const currentIndex = 0;
const gallery =
product.images.length > 1 ? (
<Grid gap={2} columns={5}>
{product.images.map((img, index) => (
<GatsbyImage
image={img.gatsbyImageData}
key={img.id}
alt={product.title}
/>
))}
</Grid>
) : null;
Make sure to not pass two values, but one value to Array.map: a function with its own optional parameter called 'index'
Consider expanding your work to a function that you can just reference, to make life easier, and code more legible, like this:
const currentIndex = 0;
const mapper = (img, index) => (
<GatsbyImage image={img.gatsbyImageData} key={img.id} alt={product.title} />
);
const gallery =
product.images.length > 1 ? (
<Grid gap={2} columns={5}>
{product.images.map(mapper)}
</Grid>
) : null;
See more here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map#syntax

React render quantity of components based on a numeric value

I want to pass in a value to a component and render multiple child components based on that value. e.g. if I pass in count={4} in props, then I want to render 4 <Icon/> components. If I pass in 5, I want to render 5, and so on.
At the moment, all I can think to do is to take the value and turn it into an array (i.e. do a for loop and push a placeholder element to an array with each iteration) and then do a map on that array. But that seems like overkill.
Is there a simple solution to this?
You can do it like this:
...
return(
Array.from({length: props.count}, () => <Icon />)
)
You're probably looking a way to map amount of children to be populated. Check this live example: https://snack.expo.io/#zvona/mapping-child-components
This is the core code from that example:
const Icon = ({index}) => (
<View><Text>{`Icon #${index + 1}`}</Text></View>
);
const Icons = ({count}) => (
Array.from({length: count}).map((_item, index) => <Icon index={index}/>)
)
const App = () => {
return (
<View style={styles.container}>
<Icons count={5} />
</View>
);
}
You can use a simple for loop for this
for(let i = 0; i < count ; i++){
return <Icon />
}
If this doesn't work, you can do the following. It's a bit modern es6 function. Try this..
{[...Array(count)].map((x, i) =>
<Icon key={i} />
)}

javascript React Native

Hi (Sorry for my english)
I have a problem, I consume a service that bring me a buttons array for a dynamic menu. This array I want to put in the screen, like button have a id for a action in specific.
Code
var sizes = []
for (var i = 0; i < this.state.tallas.length; i++) {
sizes.push(
<TouchableOpacity style={[styles.clothingSizeItem, this.state.idSize === this.state.tallas[i].id ? styles.activeClothingSizeItem:null]}
onPress={() => this.fetchSizeData(this.state.tallas[i].id)}>
<Text style={this.state.idSize === this.state.tallas[i].id ? styles.activeSizeText:null}>
{this.state.tallas[i].name}
</Text>
</TouchableOpacity>
);
}
View
render() {
return(
{sizes}
)
}
The problem is when I press a button from my dinamic menu, the button call a function that receive a parameter, but this parameter comes from service array. So I use "i" param from for, but this variable ("i") can't found after that the screen was rendered.
Screen Shot
error screen
Gracias!
You can use Array#map instead of a for loop:
const sizes = this.state.tallas.map(item => (
<TouchableOpacity style={[styles.clothingSizeItem, this.state.idSize === item.id ? styles.activeClothingSizeItem:null]}
onPress={() => this.fetchSizeData(item.id)}>
<Text style={this.state.idSize === item.id ? styles.activeSizeText:null}>
{item.name}
</Text>
</TouchableOpacity>
);
The reason the for loop doesn't work here is that the index variable i is incremented on every iteration of the loop, so by the time the callback ends up being called (long after the loop has completed), the value i is always it's final value (same as tallas.length).

Choose value relating to index in render function, React Native, ES6

I have a simple video view and all I want to do is assign the volume props to a number however it's an array of videos and each video has a different volume, so I created an array based on the index of videos now I need each video to have it's specific volume
var arr = [{vol: 1}, {vol: 3}, {vol: 8}] //3 items in render
this.state = {
volVid: arr
}
render() {
return this.props.otherUsers.map(others =>
<View key={others.infinite}>
<Video
volume={this.state.volVid}
>
</Video>
</View>
);
}
I would have put a function inside the volume props however it gave an error of expecting a number and instead receiving a function, so is there a way to reach into the array and pull the specific video volume?
Expo video component being used here.
Based on the code provided, you can just add the index to the passed callback function and use that. So:
render() {
return this.props.otherUsers.map((others, index) =>
<View key={others.infinite}>
<Video
volume={(this.state.volVid[index]) ? this.state.volVid[index].vol : 1}
>
</Video>
</View>
);
}
Added a ternary check just in case otherUsers.length > arr.length
I think what you're trying to do is to refer to your volVid array through index prop on .map():
render() {
return this.props.otherUsers.map((others, index) => {
<View key={others.infinite}>
<Video
volume={this.state.volVid[index].vol}
>
</Video>
</View>
});
}

How to map list of different svg components?

I have svgs that are required in variables
var SVG1 = require('babel-loader!svg-react-loader!../path/SVG1.svg?name=SVG1')
var SVG2 = require('babel-loader!svg-react-loader!../path/SVG2.svg?name=SVG2')
var SVG3 = require('babel-loader!svg-react-loader!../path/SVG3.svg?name=SVG3')
I use these variables as a component<SVG1/>, because it is a requirement of a svg-react-loader.
I map JSON
{this.props.jsonSting.map((item) =>
<Component key={item.id}
name={item.name}
/>
)}
How should I pass svg variables to Component so that with every map iteration in would return next svg.
I tried to add to JSON svg's names (SVG1,SVG2,SVG3) and then past it like this {item.svgname}, but it didn't work.
Any ideas?
Place your icons in an array then pass them based on index or some other variable:
const icons = [<SVG1/>, <SVG2/>, <SVG3/>]
this.props.jsonSting.map((item, index) =>
<Component key={item.id}
name={item.name}
icon={icons[index % 3]}
/>
)}
You can also create named collection with an object literal:
const icons = { SVG1: <SVG1/>, SVG2: <SVG2/>, SVG3: <SVG3/> }
this.props.jsonSting.map(item =>
<Component key={item.id}
name={item.name}
icon={icons[item.svgname]}
/>
)}

Categories

Resources