I have been struggling for hours and couldn't figuring out how to increment i
using useState([])
. I know useState([])
is an asynchronous function, and I don't know how to increment i
properly to give unique keys to each Text
Here is my code -
import React, { Component, useState, useEffect } from "react";
import {
View,
Text,
StyleSheet,
TextInput
} from 'react-native';
let weatherPanel = []
function WeatherApp(){
const [data, setData] = useState([]);
let i = 0;
const dates = [1, 2, 3, 4, 5, 6, 7, 8, 9];
const temperatures = [20, 21, 26, 19, 30, 32, 23, 22, 24];
const cities = ['LA', 'SAN', 'SFO', 'LGA', 'HND', 'KIX', 'DEN', 'MUC', 'BOM'];
const buttonPressed = () => {
weatherPanel.push(
<View style = {styles.weatherBoard}>
<Text key = {dates[i]} style = {styles.date}>{dates[i]}</Text>
<Text key = {temperatures[i]} style = {styles.temperature}>{temperatures[i]}</Text>
<Text key = {cities[i]} style = {styles.cityName}>{cities[i]}</Text>
</View>
)
setData(weatherPanel);
i = i 1;
}
// learn this to increment i properly
useEffect(()=>{
console.log(i)
}, [])
return(
<View style={styles.appBackground}>
<View style = {styles.searchBar}>
<TextInput>Text</TextInput>
</View>
<View style = {styles.weatherPanel}>
{data}
</View>
<View style = {styles.addButton}>
<Text onPress={() => buttonPressed(i)} style = {styles.temperature}>Text</Text> // CALLED buttonPressed() HERE.
</View>
</View>
)
}
I am calling button buttonPressed
at the comment, //CALLED buttonPressed() HERE.
. I am trying to add i
, that is mentioned above, to access elements of all equal length lists. Could someone help me?
Thanks!
CodePudding user response:
The effect runs once on load and then when any of the values in the dependency array change. Your useEffect has an empty dependency array, so it will never fire after load. If you want to run the effect when i
changes, it should be
useEffect(()=>{
console.log(i)
}, [i]);
Read more about useEffect here in the docs.
If you have control over the data you're using, it's more intuitive to store all the related info in one object, rather than in three separate arrays linked only by index.
const weatherArray = [
{ date: 1, temperature: 20, city: 'LA' },
// ...
You should also store i
in state rather than as a plain variable. Keeping it in state will tell React to re-render the component when it changes.
const [i, setI] = useState(0);
// ...
setI(oldI => oldI 1);
CodePudding user response:
In your case, you would like to display data in loops for some data set. I would suggest you to solve it without iterator and use map()
function instead.
import React, { Component, useState, useEffect } from "react";
import {
View,
Text,
StyleSheet,
TextInput
} from 'react-native';
function WeatherApp(){
const [data, setData] = useState([]);
const dates = [1, 2, 3, 4, 5, 6, 7, 8, 9];
const temperatures = [20, 21, 26, 19, 30, 32, 23, 22, 24];
const cities = ['LA', 'SAN', 'SFO', 'LGA', 'HND', 'KIX', 'DEN', 'MUC', 'BOM'];
const buttonPressed = () => {
if (data.length >= dates.length) return; //Prevent out of bound
setData([
...data, //get old data array
{
//New data set
dates: dates[data.length],
temperatures: temperatures[data.length],
cities: cities[data.length]
}
]);
}
return (
<View style={styles.appBackground}>
<View style={styles.searchBar}>
<TextInput>Text</TextInput>
</View>
<View style={styles.weatherPanel}>
{
//Loop the data by map function
data.map((item, index) => {
return (
<View style={styles.weatherBoard}>
<Text key={item.dates} style={styles.date}>{item.dates}</Text>
<Text key={item.temperatures} style={styles.temperature}>{item.temperatures}</Text>
<Text key={item.cities} style={styles.cityName}>{item.cities}</Text>
</View>
)
})
}
</View>
<View style={styles.addButton}>
<Text onPress={() => buttonPressed()} style={styles.temperature}>Add Item</Text>
</View>
</View>
)
}