why my react native component keep refreshing? - javascript

hi i am trying to build react native app i am using expo
i build a screen to show data and calculate a number using hooks
but i face that my component keep rendering so i cant press in the buttons easily , which lead me to can't calculate the number ,
this is my code how i can stop this continuous refreshing
if i but console statements inside the component it keep printing in console and not stop
import React, { useState, useEffect } from "react";
import { AsyncStorage } from "react-native";
import { Button } from "react-native-paper";
import axios from "axios";
import { View, Text, TextInput, StyleSheet } from "react-native";
export default function Confirm() {
const [info, setInfo] = useState([]);
const [value, onChangeText] = React.useState("0");
const [total, setTotal] = useState("0");
const [selectedLocation, setSelectedLocation] = useState({});
try {
//Retrieving user token, reserved nanny information and user location value from AsyncStorage
AsyncStorage.multiGet(["token", "nany", "location"]).then((res) => {
var nany = JSON.parse(res[1][1]);
var location = JSON.parse(res[2][1]);
setInfo(nany);
console.log("hi3");
setSelectedLocation(location);
});
} catch (error) {
throw error;
}
const onSubmit = () => {
axios
.post("http://192.168.127.43:5000/send2", [selectedLocation, total, info])
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
};
function calculateTotal() {
console.log(info.cost * value);
var totalCost = info.cost * value;
setTotal(totalCost);
alert("Your reservation done \n Your service costs: " + total);
}
return (
<View>
<>
<View>
<Card
title={info.name}
caption={info.cost + " JD /H"}
>
<View
>
<Text>{info.place}</Text>
</View>
</Card>
<View>
<View>
<Text style={styles.text}>
Enter how many hours you need our service
</Text>
<TextInput
style={styles.input}
onChangeText={(text) => onChangeText(text)}
value={value}
></TextInput>
</View>
<View>
<Button
mode="contained"
onPress={calculateTotal}
>
<Text>Calculate total</Text>
</Button>
</View>
</View>
<View>
<View>
<Button
mode="contained"
onPress={onSubmit}
>
<Text>Done</Text>
</Button>
</View>
<View>
<Button
title="Submit"
mode="contained"
>
<Text>Cancel</Text>
</Button>
</View>
</View>
</View>
</>
</View>
);
}
// export default Confirm;

Nothing looks wrong in your code but for safer side wrap try and catch inside useEffect.
useEffect(()=>{
try {
//Retrieving user token, reserved nanny information and user location value from AsyncStorage
AsyncStorage.multiGet(["token", "nany", "location"]).then((res) => {
var nany = JSON.parse(res[1][1]);
var location = JSON.parse(res[2][1]);
setInfo(nany);
console.log("hi3");
setSelectedLocation(location);
});
} catch (error) {
throw error;
}
,[]);

Related

I Can't get my exact location using expo-location

THE CODE USING REACT-NATIVE AND EXPO-LOCATION:
import {
View,
Text,
Alert,
SafeAreaView,
RefreshControl,
StyleSheet,
ActivityIndicator,
ScrollView
} from 'react-native';
import React, {
useEffect,
useState
} from 'react';
import * as Location from 'expo-location'
const openWeatherKey = 'cbb62d0f2653b471dbf6ca28aebb813f'
let url = `http://api.openweathermap.org/data/2.5/onecall?&units=metric&exclude=minutely&appid=${openWeatherKey}`
const Weather = () => {
const [forecast, setForecast] = useState(null)
const [refreshing, setRefreshing] = useState(false)
const loadForecast = async () => {
setRefreshing(true)
const {
status
} = await Location.requestForegroundPermissionsAsync();
if (status !== 'granted') {
Alert.alert('Permission to acces location was denied')
}
let location = await Location.getCurrentPositionAsync({
enableHighAccuracy: true
})
const response = await fetch(`${url}&lat=${location.coords.latitude}&lon=${location.coords.longitude}`)
const data = await response.json()
if (!response.ok) {
Alert.alert('error something went wrong')
} else {
setForecast(data);
}
setRefreshing(false)
}
useEffect(() => {
loadForecast()
}, [])
if (!forecast) {
return (
<SafeAreaView style={styles.loading}>
<ActivityIndicator size='large'/>
</SafeAreaView>
)
}
const current = forecast.current.weather[0]
return (
<SafeAreaView style={styles.container}>
<ScrollView
refreshControl={
<RefreshControl
refreshing={refreshing} onRefresh={() => loadForecast()}/>
}
style={{marginTop:50}}
>
<Text style={styles.title}>
Current Weather
</Text>
<Text style={{alignItems:'center', textAlign:'center'}}>
Your Location
</Text>
<View>
</View>
</ScrollView>
</SafeAreaView>
)
}
export default Weather
)
THE ERROR: 'Error something went wrong'
But i dont understand why he is not able to get the location?
Does somebody know the answer? i think it goes wrong at const response. Also when i use the standard Code for gettting a location from expo-location docs it works?

Async Storage not working (React native expo), no error given in console, but everytime I reload nothing is stored

I'm trying to use Async Storage for a note app, I created a component called task.js as a template for todos, an navigation.js component for nav, and home.js for the main screen all display with <navigation /> inapp.js, I added a funcction to store object value using async storage, but is not working, everytime I hard reload the app everything will be gone but it is not giving me any errors, I don't know where to start
here is my Home.js
import React, {useState} from 'react';
import { Keyboard, KeyboardAvoidingView, Platform, StyleSheet, Text,
TextInput, TouchableOpacity, View, SafeAreaView, ScrollView, Image } from 'react-native';
import Task from '../components/Task';
import AsyncStorage from '#react-native-async-storage/async-storage';
export default function Home({ navigation }) {
const [task, setTask] = useState();
const [taskItems, setTaskItems] = useState([]);
React.useEffect ( () => {
save(taskItems);
}, [taskItems])
React.useEffect (() => {
getsave();
}, [])
const handleAddTask = () => {
Keyboard.dismiss();
setTaskItems([...taskItems, task])
setTask(null);
}
const completeTask = (index) => {
let itemsCopy = [...taskItems];
itemsCopy.splice (index, 1);
setTaskItems(itemsCopy)
}
const save = async taskItems =>{
try {
const savetask = JSON.stringify(taskItems)
await AsyncStorage.setItem('tasksave', savetask)
} catch (e) {
console.log(e);
}
};
const getsave = async () => {
try {
const taskItems = await AsyncStorage.getItem('tasksave');
if (taskItems != null){
setTaskItems(JSON.parse(taskItems));
}
} catch (error) {
console.log(e);
}
};
return (
<SafeAreaView style={styles.container}>
<View style={styles.tasksWrapper}>
<Text style={styles.sectionTitle}>Your stuff:</Text>
<TouchableOpacity onPress={() => navigation.navigate('About')}>
<Text style={styles.about}>About</Text>
</TouchableOpacity>
<ScrollView style={styles.items}>{
taskItems.map((item, index) => {
return (
<View key={index}>
<TouchableOpacity onPress={ () => navigation.navigate("Gas", {item})}>
<Task text={item} navigation={navigation} />
</TouchableOpacity>
<TouchableOpacity onPress={() => completeTask(index)} style={styles.deleteW}>
<Image style={styles.delete} source={require('../components/remove.png')}></Image>
</TouchableOpacity>
</View>
)
})
}
</ScrollView>
</View>
<KeyboardAvoidingView
behavior={Platform.OS === "ios" ? "padding" : "height"}
style={styles.textwrapper}>
<TextInput style={styles.input} placeholder={'message'} value={task} onChangeText={text => setTask(text)}></TextInput>
<TouchableOpacity onPress={() => handleAddTask()}>
<View style={styles.addWrap}>
<Text style={styles.add}>+</Text>
</View>
</TouchableOpacity>
</KeyboardAvoidingView>
</SafeAreaView>
);
}
Here's my Task.js:
import React from "react";
import { View, Text, StyleSheet, Image, TouchableOpacity } from "react-native";
const Task = (props, {navigation}) => {
return (
<View style={styles.item}>
<View style={styles.itemleft}>
<Image style={styles.lightball} source={require('./arabic.png')}></Image>
<Text style={styles.itemtext}>{props.text}</Text>
</View>
<Image style={styles.arrow} source={require('./rightarrow.png')}></Image>
</View>
)
}
const styles = StyleSheet.create({
export default Task;
I hope is a quick read, I took out all the style stuff but this is still kinda long sorry, if you think it has something to do with my app.js or nav.js I can give you those too, I usually slove these bugs on my own but I just have no idea where to begin cause I'm not getting any error messages, thank you

How to push data in the setState of array-type state?

I am having a state data. I wanted to push a new entry of the form
{ task:'ANy task',key:Math.random().toString() }
in the data array while using setData.
I had tried many ways mentioned here, but don't klnow why its not working.
Here's my code.
import React, { useState } from "react";
import { StyleSheet, Text, View, TextInput, Button } from "react-native";
import { StatusBar } from "expo-status-bar";
const Addtask = ({navigation}) => {
const [data,setData] = useState([]);
console.log("from add = ",data)
const [task, setTask] = useState("");
const handleSubmit = () => {
console.log("submit pressed for task = ", task)
const updatedData = [...data,{
task:task,
key: Math.random().toString(),
}]
//here i am setting the data
setData(prevState => [...prevState,updatedData]);
console.log("data after adding task",data)
navigation.navigate("Tasklist",{data:data})
}
return (
<View style={styles.container}>
<StatusBar style="light" backgroundColor="midnightblue" />
<View>
<Text style={styles.text}>Add Task Here</Text>
</View>
<View>
<TextInput
style={styles.input}
onChangeText={setTask}
value={task}
onChange={setTask}
placeholder="Type your task"
keyboardType="ascii-capable"
/>
</View>
<View style={styles.buttoms}>
<View style={{margin:4}}>
<Button color={'red'} onPress={()=>{navigation.goBack()}} title="Cancel"></Button>
</View>
<View style={{margin:4}}>
<Button color={'lightblue'} onPress={()=>setTask('')} title="Clear"></Button>
</View>
<View style={{margin:4}}>
<Button color={'green'} onPress={handleSubmit} title="Save"></Button>
</View>
</View>
</View>
);
};
const styles = StyleSheet.create({
.
.
.
});
export default Addtask;
To debug, I had used console stmts which reveals that the task value is coming in the handleSubmit() correctly but it is not getting pushed.
Log
submit pressed for task = Morning bike ride.
data after adding task Array []
Because You are already have
const updatedData = [...data,{
task:task,
key: Math.random().toString(),
}]
You don't need setData(prevState => [...prevState,updatedData]) you can just assign the updatedData to setData like setData(updatedData)
You can use
setData(current => [...current, {
task:task,
key: Math.random().toString(),
}])
Then you don't need updatedData

Undefined is not an object (...) react native

I have a problem with React-Native. I want to show data from Django to React-Native, but I can't show one data, this is the code:
import React, { useState, useEffect } from "react";
import { StyleSheet, View, Text, Image, FlatList } from "react-native";
import client from "./../../api/client";
const DetailView = ({navigation, route}) => {
const [detail, setDetail] = useState("");
const { objurl } = route.params;
const getDetail = async (url) => {
try {
const response = await client.get(url);
if (!response.ok) {
setDetail(response.data);
}
} catch (error) {
console.log(error);
}
};
useEffect(()=>{ getDetail(objurl); }, [])
console.log(detail.habilidad_usuario.nombre_habilidad);
return (
<View style={styles.center}>
<Image
style={styles.usuarioImage}
source={{
uri: detail.foto_usuario,
}}
/>
<Text style={styles.name}>{detail.nombre_usuario} {detail.apellido_usuario}</Text>
<Text style={styles.name}>{detail.habilidad_usuario.nombre_habilidad}</Text>
<Text style={styles.description}>{detail.descripcion_usuario} </Text>
<Text style={styles.body}>Dirección: {detail.direccion_usuario} </Text>
<Text style={styles.body}>Celular: {detail.id_usuario} </Text>
<FlatList
data={detail.usuario_comentado}
keyExtractor={(item) => item.id.toString()}
renderItem={({ item }) => {
return (
<Text style={styles.body}>Comentario: {item.contenido_comentario} </Text>
);
}}
/>
</View>
);
}
The problem is in the line:
<Text style={styles.name}>{detail.habilidad_usuario.nombre_habilidad}</Text>
and It's the result:
enter image description here
The others data is rendering very well.
The data from Django Rest is:
enter image description here

I am trying to run this react native screen where it fetches data for me. This gets run when i click the text from a home screen. But it's not working

This is where my home screen is:
import React, { useState } from "react";
import {
StyleSheet,
View,
Text,
Button,
FlatList,
TouchableOpacity,
} from "react-native";
import { globalStyles } from "../styles/global";
import Card from "../shared/card";
import FlatButton from "../shared/button";
import { TextInput } from "react-native-gesture-handler";
import { AntDesign } from "#expo/vector-icons";
import Weather from "./weather";
export default function Home({ navigation }) {
//add state here
const [reviews, setReviews] = useState([
{ title: "Let's Snowboard", rating: 4, body: "blue", key: 1 },
]);
const [city, setCity] = useState("");
return (
<View style={globalStyles.container}>
<View style={styles.searchBox}>
<TextInput
placeholder="search"
placeholderTextColor="lightcoral"
style={styles.searchText}
onChange={(text) => setCity(text)}
/>
<TouchableOpacity style={styles.buttonTouch} onPress={Weather}>
<AntDesign name="search1" size={28} color="lightcoral" />
</TouchableOpacity>
</View>
<FlatList
data={reviews}
renderItem={({ item }) => (
<TouchableOpacity
onPress={() => navigation.navigate("Weather", item)}
>
<Card>
<Text style={globalStyles.titleText}>{item.title}</Text>
</Card>
</TouchableOpacity>
)}
/>
<FlatButton text="Let's snowboard?" />
</View>
);
}
For my weather screen:
import React, { useState } from "react";
import { StyleSheet, Text, View, Image } from "react-native";
import { globalStyles } from "../styles/global";
const Weather = () => {
const [date, setData] = useState([]);
const [icon, setIcon] = useState("");
const [cityDisplay, setCityDisplay] = useState("");
const [desc, setDesc] = useState("");
const [main, setMain] = useState("");
const [humidity, setHumidity] = useState("");
const [pressure, setPressure] = useState("");
const [visibility, setVisibility] = useState("");
const [temp, setTemp] = useState("");
async function fetchWeather() {
try {
const response = await fetch(
"https://samples.openweathermap.org/data/2.5/weather?q=London,uk&appid=***"
);
const json = await response.json();
setData({ data: json });
setTemp({ temp: (json.main.temp - 273.15).toFixed(2) + " C" });
setCityDisplay({ cityDisplay: json.name });
setIcon({ icon: json.weather[0].icon });
setMain({ main: json.weather[0].main });
setHumidity({ humidity: json.main.humidity + " %" });
setPressure({ pressure: json.main.pressure + " hPa" });
setVisibility({
visibility: (json.visibility / 1000).toFixed(2) + " km",
});
} catch (err) {
console.warn("error");
}
}
return (
<View style={styles.weatherBox}>
<View style={styles.weatherHolder}>
<Image
source={{
uri: "http://openweathermap.org/img/wn/" + setIcon + "#2x.png",
}}
style={styles.weatherImage}
/>
<View>
<Text style={styles.temperature}>{temp}</Text>
<Text>{cityDisplay}</Text>
</View>
</View>
</View>
);
};
Essentially, my goal is to click the card text where it says :let's snowboard. Once clicked, it should redirect me to the weather screen where at the moment, it will show me the current temperature and the name of the city. I am not sure why it's not showing. Im assuming it has something to do with my weather screen.
I had tested out making another simple screen where it would show the values of my current state 'reviews'. I was able to click the card and redirect me to another screen where it shows the rating value and the body.
This is the first time I've dealt with apis. Any guidance would be much appreciated(:
I am fairly certain that you do not actually call the fetchWeather function. In the Weather component you define the function with async function fetchWeather() {...}. However, that is only a function definition. You need to actually call it like this: fetchWeather(); which I think you can do right below the definition like the example below.
async function fetchWeather() {
// code that you want to execute in the function
}
// Actual function call
fetchWeather();
EDIT (concerning state management):
I would definitely recommend reading most of the React Hooks documentation to get a full grasp, but I will still address how you handle state.
At this location in the docs it shows exactly what I believe your issue to be.
Whenever you try to set state you do this: setVariable({ variableName: newValue});, but that is how you are supposed to set state inside of a class. However, fetchWeather() is a function, and functions are supposed to update state like this: setVariable(newValue);

Categories