create multiple buttons in a view via loop - javascript

I want to create multiple custom buttons for my react-native app.
I'm using an array with all the informations in it and I want to iterate over all buttons in the array and create all buttons in one single view.
I tried something like this:
<View>
for( let i=0; i<numberButtons; i++) {
<TouchableOpacity style={[styles.mapView, this.props.mapViewStyle]} >
<Image
style={[styles.image, this.props.imageStyle]}
source={{uri: 'https://facebook.github.io/react/img/logo_og.png'}}
/>
</TouchableOpacity>
}
</View>
That doesn't seem to work. I get errors from the react-native framework so I guess you can't do js in a view?
How can I do this?

You can do it like this:
renderButtons = () => {
const buttons = [];
for( let i = 0; i < numberButtons; i++) {
buttons.push(
<TouchableOpacity style={[styles.mapView, this.props.mapViewStyle]}>
<Image
style={[styles.image, this.props.imageStyle]}
source={{uri: 'https://facebook.github.io/react/img/logo_og.png'}}
/>
</TouchableOpacity>
)
}
return buttons;
}
render() {
return (
<View>
{this.renderButtons()}
</View>
)
}

Related

Passing in parameters to dynamically created components React Native

let itemName;
for (let j=0; j< Object.keys(menu[location][mealTime][sectionName]).length; j++) {
itemName = Object.keys(menu[diningHall][mealTime][sectionName])[j];
if (processAllergyArr(menu[diningHall][mealTime][sectionName][itemName]['itemAllergyArr'], exclusionArr, inclusionArr)) {
if (itemName.toLocaleLowerCase().indexOf(search.toLocaleLowerCase()) != -1) {
console.log(itemName)
arrOfItems.push(
<View key={j} style={{borderWidth: 1, height: 40}}>
<TouchableOpacity
key={j}
onPress={() => {onItemClick(itemName)}}
style={{height: '100%', display: 'flex', flexDirection:'row'}}
>
Here I have a variable called itemName that I try to pass in as a parameter in a function called onPress of my touchable opacity component. My touchable opacity component is in an array of components of its kind which are then included in the return function of my component.
The problem here is that the onPress function passes in the same exact parameter into onItemClick regardless of which item is associated with the opacity button.
The console.log(itemName) will log different item names but the function in onPress will use the same exact one
I was thinking that bind may be useful in this scenario but wasn't sure of how to implement it.
The reason is you declared itemName outside of for loop.
Since you are trying to make a component, it shouldn't be used like pushing values into an array.
UI Rendering will be happen in your page and this will result in itemName being the last value of its signed value.
A way to solve this is to put itemName inside of your For-Loop
for (let j=0; j< Object.keys(menu[location][mealTime][sectionName]).length; j++) {
const itemName = Object.keys(menu[diningHall][mealTime][sectionName])[j];
if (processAllergyArr(menu[diningHall][mealTime][sectionName][itemName]['itemAllergyArr'], exclusionArr, inclusionArr)) {
if (itemName.toLocaleLowerCase().indexOf(search.toLocaleLowerCase()) != -1) {
console.log(itemName)
arrOfItems.push(
<View key={j} style={{borderWidth: 1, height: 40}}>
<TouchableOpacity
key={j}
onPress={() => {onItemClick(itemName)}}
style={{height: '100%', display: 'flex', flexDirection:'row'}}
>
Declaring inside for loop should do the trick.

Basic Beginner React-Native State Question

Hello guys I just started learning React-Native and I have a question about state.
I was practicing this concept trying to make a button that shows how many times I've pressed it.
My plan was to make a variable called clicks which will increase by 1 each time I press it and set the clickState to clicks. This is my code.
export default function App() {
const [clickState, setClicks] = useState(0)
let clicks = 0
return (
<View style = {styles.container}>
<StatusBar style="auto" />
<TouchableOpacity style={styles.button} onPress={()=>{setClicks(++clicks); console.log(clicks)}}>
<Text>Clicks : {clickState}</Text>
</TouchableOpacity>
</View>
);
}
this is the console
But apparently something is wrong and my clicks value goes random between 1 and 2 each time I click it instead of increasing by 1.
So I was curious about what I was doing wrong and why the values don't increase as I expected. I would also be glad if you showed how you would implement it if there is a better way.
Thanks guys.
You only need to update clickState, no need of variable clicks.
Also it won't rerender if we increment state value directly, so we should increment state by taking its previous state value like shown below
export default function App() {
const [clickState, setClicks] = useState(0)
return (
<View style = {styles.container}>
<StatusBar style="auto" />
<TouchableOpacity style={styles.button} onPress={()=>setClicks(prevState => prevState + 1)}>
<Text>Clicks : {clickState}</Text>
</TouchableOpacity>
</View>
);
}

How to make a line break in textinput after insert a image component inside of it? REACT-NATIVE

im new in react-native and im doing a bloc note, the problem now is that i want to allow the user put images with the note, something like this:
my structure for this for now is this:
render() {
return (
<>
<View style = {this.styles.container}>
<TextInput style = {this.styles.TextInput_title} placeholder = "Title" multiline = {true} maxLength = {80} value = {this.state.title} onChangeText = {title => this.setState({title: title})}></TextInput>
<View style = {this.styles.textinput_container}>
<TextInput style = {this.styles.textinput} multiline = {true} onChangeText = {content => this.setState({content: content})}><Text>{this.state.content}{"\n"}</Text>
<Text>{this.state.img}</Text>
</TextInput>
<Button title = "Add image" onPress = {this.add_Image}></Button>
<Button title = "Save Changes" onPress = {this.save_Changes}></Button>
</View>
</View>
}
add_Image = () => {
this.setState({content: this.state.content + "\n\n\n"});
const img = <Image source = {require("../img/ny.png")} style = {{width: 100, height: 100}}></Image>
this.setState({img:img});
}
for now im just using a button to add the image to see if it works, but i get this:
as you can see, the pointer (the blue line) is still there and doesnt does a line break, maybe is the way that im using to do this, but like i said, im new and for now i dont know another way to do this, so if anyone can help me, really will appreciate :)
You could achieve this by some modifications to the style:
E.G:
<Text style={{ flex: 1, marginTop: '25%' }}>{this.state.img}</Text>
Where,
marginTop: Gona gives you the proportion of the space you want to leave on top.
flex: Set it on 1 it's going to put it on its on space.

onPress doesn't detect props of touchable opacity in react native

onPress doesn't show me the id of my touchable opacity component when I press on it. He just shows me undefined.
render() {
var rows = [];
var i = 0;
while(i<5){
rows.push(<TouchableOpacity id={i} activeOpacity={0.9} onPress={() => alert(this.props.id)}>
<View>
</View>
</TouchableOpacity>);
i++;
}
return {rows}
}
I want to when I press on it, it shows the id of touchable opacity. Please help me
The component you have for this render() function would need to have a prop id for this to show an alert, but I think you are wanting to show each value of i. Due to i never going out of scope within this function (as it is var), if you attempted to just do alert(i) it would show 5 for each button, but if you use const inside the while to store the current value of i, each button will have the correct value:
while (i < 5) {
const temp = i;
rows.push(
<TouchableOpacity
id={i}
activeOpacity={0.9}
onPress={() => alert(temp)}
>
<View />
</TouchableOpacity>,
);
i++;
}
You can't use a prop you are assigning in another prop you are assigning like you were trying to do.

Long press on custom checkbox

I'm trying to create a long-press handler on the checkbox. The package with the component is https://www.npmjs.com/package/react-native-checkbox — i think it is default one. The problem is that checkbox intercepts onPressIn and onPressOut events and my TouchableWithoutFeedback component doesn't emit anything. Here is the code:
var pressStart = 0;
const pressTimeout = 400;
function pressIn() {
alert(0);
pressStart = parseInt((new Date()).getTime() / 1000);
}
function pressOut() {
var pressEnd = parseInt((new Date()).getTime() / 1000);
if (pressEnd - pressStart < pressTimeout) return;
alert(1);
}
return (
<View style={style.container}>
<TouchableWithoutFeedback onPressIn={pressIn} onPressOut={pressOut}>
<View>
{/*<Text>asdasdasd</Text>*/}
<CheckBox checked={this.state.done} labelStyle={style.checkbox} label={this.state.name} onChange={toggleChecked} />
</View>
</TouchableWithoutFeedback>
</View>
);
Also, if i use Text component instead of CheckBox — it fires pressIn event, but pressOut doesn't work (i see alert(0), but not alert(1)).
Ok, at first, i've created a fork from the react-native-checkbox package that supports onPressIn and onPressOut events:
https://www.npmjs.com/package/react-native-checkbox-touch-events
But I think it will be useless, cause you can do some like this (I don't promise it works):
<TouchableWithoutFeedback delayPressIn={0} onPressIn={pressIn} onPressOut={pressOut}>
<View>
<CheckBox onPress={press} />
</View>
</TouchableWithoutFeedback>
Anyway, I will use my package, I'm too lazy to test this solution and don't want to get disappointed with my work.
And also: don't divide getTime() by 1000, if you want milliseconds...

Categories