Can't set state in js react-native - javascript

Getting error while trying to setState in React Native.
Code
import React from "react";
import { TextInput, Text, View, Button, Alert } from "react-native";
const UselessTextInput = () => {
state = { currentDate: "" };
const setCurentDate = (val) => {
this.setState({currentDate : val});
};
const [value, onChangeText] = React.useState("");
return (
<View>
<Text
style={{
alignSelf: "center",
marginTop: 60,
fontWeight: "bold",
fontSize: "25",
}}
>
BirthReminder
</Text>
<Text style={{ alignSelf: "center", marginTop: 15, fontSize: 15 }}>
Enter your friend's birthdate, please
</Text>
<TextInput
clearTextOnFocus={true}
style={{
height: 40,
borderColor: "gray",
borderWidth: 1,
marginTop: 20,
width: 250,
alignSelf: "center",
}}
onChangeText={(value) => setCurentDate(value)}
value={value}
/>
<Button title="Add to list"></Button>
</View>
);
};
export default UselessTextInput;
Error
TypeError: undefined is not an object (evaluating '_this.setState')

useState Hook
Functional components don't have access to setState method but useState hook.
useState hook works by defining the name of value, e.g. foo followed by it's setter. It's a convention to name the setter with the same name as that of value with set prefix, i.e. setFoo
const [foo, setFoo] = useState('hi');
// pass the initial value here -^^-
Solution
import { useState } from 'react';
import { TextInput } from 'react-native';
const Component = () => {
const [value, setValue] = useState('');
return <TextInput value={value} onChangeText={setValue} />;
};

this.setState isn't allowed in functional component. Try to use React.useState for currentDate
const [currentDate, setCurrentDate] = React.useState("");
...
const setCurentDate = (val) => {
setCurrentDate(val);
};

I think you got a bit mixed up
replace this as this is the syntax if you use Class component
state = { currentDate: "" };
const setCurentDate = (val) => {
this.setState({currentDate : val});
};
with:
const [date, setDate] = React.useState();
const setCurentDate = (val) => {
setDate(val);
};
and have a look at the documentation

Related

TypeError: undefined is not an object (evaluating '_this.camera = _ref')

-App dev in React Native-
Hello,
I have a problem with Expo Camera. Here an error is referred when you want to take a picture.
"TypeError: undefined is not an object (evaluating '_this.camera = _ref')" / Scan.js.
If the app is freshly updated with Expo, everything works. But as soon as you continue programming and another error occurs, this error appears and doesn't go away until you refresh the app again.
I have tried a lot, but I need help here.
Scan.js
import React, { Component, useState, useEffect } from 'react';
import { View, Text, StyleSheet, TouchableOpacity, Image } from 'react-native';
import {launchCamera, launchImageLibrary} from 'react-native-image-picker';
import {Camera, Constants} from 'expo-camera';
import * as MediaLibrary from 'expo-media-library';
import * as Haptics from 'expo-haptics';
import Images from '../assets/icon/index'
const Scan = () => {
const [hasPermission, setHasPermission] = useState(null);
const [type, setType] = useState(Camera.Constants.Type.back);
const [status, requestPermission] = MediaLibrary.usePermissions();
useEffect(() => {
(async () => {
const { status } = await Camera.requestCameraPermissionsAsync();
setHasPermission(status === 'granted');
})();
}, []);
if (hasPermission === null) {
return <View/>;
}
if (hasPermission === false) {
return <Text>No access to camera</Text>;
}
takePicture = async () => {
if (this.camera) {
let photo = await this.camera.takePictureAsync();
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium);
console.log(photo.uri);
MediaLibrary.saveToLibraryAsync(photo.uri);
}
};
return (
<View style={styles.container}>
<Camera style={styles.camera}
type={type}
ref={ref => {
this.camera = ref;
}}>
<View style={styles.buttonContainer}>
<TouchableOpacity
style={styles.button}
onPress={() => {
setType(
type === Camera.Constants.Type.back
? Camera.Constants.Type.front
: Camera.Constants.Type.back
);
}}
>
<Image source={Images.camera} style={styles.icon}></Image>
</TouchableOpacity>
<TouchableOpacity
style={styles.button}
onPress={takePicture}
>
<Text style={styles.text}>Take</Text>
</TouchableOpacity>
</View>
</Camera>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
camera: {
flex: 1,
},
buttonContainer: {
flex: 1,
backgroundColor: 'transparent',
flexDirection: 'row',
margin: 20,
top: 0,
},
button: {
flex: 0.1,
alignSelf: 'flex-end',
alignItems: 'center',
},
text: {
fontSize: 18,
color: 'white',
},
icon : {
tintColor: 'white',
},
})
export default Scan; ```
Create a new camera reference and attach it to the Camera component.
import { useRef } from 'react';
...
const cameraRef = useRef<Camera>(null);
...
<Camera ref={cameraRef} ... />
In your takePicture function replace this.camera.takePictureAsync with cameraRef.current?.takePictureAsync
Error: Function components cannot have string refs. We recommend using useRef() instead. Learn more about using refs safely here: https://reactjs.org/link/strict-mode-string-ref.
This is because the guy who answered used TypeScript.
Simply replace
const cameraRef = useRef(null);
with
const cameraRef = useRef(null);

Firebase v9 not adding docs

I'm working with Firebase v9. The authentication works fine, but the Firestore does not work me for some reason. I don't even get an error--it just doesn't do anything.
I tried addDocs() but still nothing works.
EDIT: actually , i was using the firebase #9.1.0 i upgraded it to #9.6.7 and it worked perfectly fine ! i had to downgrade from #9.6.8 ( the latest ) to #9.1.0 because of the error ( Can't find variable: IDBIndex ) !
import React, { useLayoutEffect, useState } from "react";
import {
Text,
View,
StyleSheet,
TextInput,
TouchableOpacity,
KeyboardAvoidingView,
Platform,
ScrollView,
Alert,
} from "react-native";
import { AntDesign, Ionicons } from "#expo/vector-icons";
import { doc, setDoc } from "firebase/firestore";
import { db } from "../../firebase/firebaseConfig";
const NewChat = ({ navigation }) => {
const [input, setInput] = useState("");
useLayoutEffect(() => {
navigation.setOptions({
title: "Add a new Chat",
headerBackTitle: "Chats",
});
}, [navigation]);
const AddChat = async () => {
const myDoc = doc(db, "Chats", input);
const docData = {
chatName: input,
};
setDoc(myDoc, docData).then(() => {
navigation.goBack();
});
};
return (
<ScrollView>
<View
style={{
marginTop: 20,
marginHorizontal: 20,
borderColor: "black",
borderWidth: 1,
}}
>
<View style={styles.container}>
<AntDesign
name="wechat"
size={40}
color="black"
style={{ alignSelf: "center" }}
/>
<TextInput
placeholder="Enter a chat name"
value={input}
onChangeText={(text) => {
setInput(text);
}}
style={{ flexGrow: 1, marginLeft: 20 }}
/>
<TouchableOpacity style={{ alignSelf: "center" }} onPress={AddChat}>
<Ionicons name="checkmark-done-circle" size={40} color="black" />
</TouchableOpacity>
</View>
</View>
</ScrollView>
);
};
const styles = StyleSheet.create({
container: {
flexDirection: "row",
backgroundColor: "white",
justifyContent: "center",
height: 60,
},
});
export default NewChat;
The function setDoc() asynchronously returns a promise which means all you're missing is the await keyword before you call the function.
const AddChat = async () => {
const myDoc = doc(db, "Chats", input);
const docData = {
chatName: input,
};
await setDoc(myDoc, docData).then(() => {
navigation.goBack();
});
};
Edit: I think I see the real problem, It has to do with the v9 document reference. Try using collection() within the document reference.
const AddChat = async () => {
const myDoc = doc(collection(db, "Chats"), input);
const docData = {
chatName: input,
};
await setDoc(myDoc, docData).then(() => {
navigation.goBack();
});
};

Set Hook in React Native

I can't set a state with Hooks in React Native. After call setMyvariable, I get an [object Object].
I can see that with a simple alert...
Please... Help me... Why append this...?
This is the code:
import * as React from 'react';
import { useState } from 'react';
import { View, TextInput, Button, StyleSheet } from 'react-native';
const PageArticle = () => {
const [FindRollNo, setFindRollNo] = useState("12");
const [RollNo, setRollNo] = useState(undefined);
const [StudentName, setStudentName] = useState(undefined);
const [Course, setCourse] = useState(undefined);
const SearchRecord = () => {
var FindRollNo = {FindRollNo};
alert(FindRollNo);
};
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }, styles.viewStyle}>
<TextInput
placeholder={'Enter RollNo'}
placeholderTextColor={'#ff0000'}
keyboardType={'numeric'}
style={styles.txtStyle}
onChangeText={(value) => setFindRollNo(value)}
/>
<Button title={'Find Record'} onPress={SearchRecord} />
<TextInput
style={styles.txtStyle}
value={RollNo}
/>
<TextInput style={styles.txtStyle} value={StudentName} />
<TextInput style={styles.txtStyle} value={Course} />
{/*<Text>Article Screen ciao </Text>*/}
</View>
);
};
You've wrapped FindRollNo in curly braces, which turns the value into an object.
Fortunately, you can access FindRollNo directly. Here's an Expo Snack showing how:
https://snack.expo.dev/#coolsoftwaretyler/trembling-blueberries
The code looks like this. Pay attention mostly to the difference in SearchRecord, which just alerts FindRollNo directly without creating a new variable or anything.
import * as React from 'react';
import { useState } from 'react';
import { View, TextInput, Button, StyleSheet } from 'react-native';
const PageArticle = () => {
const [FindRollNo, setFindRollNo] = useState("12");
const [RollNo, setRollNo] = useState(undefined);
const [StudentName, setStudentName] = useState(undefined);
const [Course, setCourse] = useState(undefined);
const SearchRecord = () => {
alert(FindRollNo);
};
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<TextInput
placeholder={'Enter RollNo'}
placeholderTextColor={'#ff0000'}
keyboardType={'numeric'}
onChangeText={(value) => setFindRollNo(value)}
/>
<Button title={'Find Record'} onPress={SearchRecord} />
<TextInput
value={RollNo}
/>
<TextInput value={StudentName} />
<TextInput value={Course} />
{/*<Text>Article Screen ciao </Text>*/}
</View>
);
};
export default PageArticle

delete list element using filter method

I am working on todo list in native , i have a function called onDelete but when i click on it , it delete all element in list and after then program crashed.
this is my main file where i have stored value as key , value pair
export default function App() {
const [courseGoal, setCourseGoal] = useState([]);
const [count, setCount] = useState('');
const submitHandler = () => {
setCourseGoal((currGoal) => [
...currGoal,
{ key: Math.random().toString(), value: count },
]);
};
console.log('App', courseGoal)
return (
<View style={styles.container}>
<SearchBar
setCourseGoal={setCourseGoal}
count={count}
setCount={setCount}
submitHandler={submitHandler}
/>
<ListItem courseGoal={courseGoal} setCourseGoal={setCourseGoal} courseGoal={courseGoal}/>
</View>
);
}
this is my list component where i am facing issue, you can see ondelete here.
import React from "react";
import { StyleSheet, Text, TouchableOpacity } from "react-native";
import { FlatList } from "react-native-web";
export default function ListItem(props) {
const onDelete = (goalId) => {
props.setCourseGoal((currGoal) => {
currGoal.filter((goal) => goal.key !== goalId);
console.log("clicked", props.courseGoal[0].key);
});
};
return (
<FlatList
data={props.courseGoal}
keyExtractor={(item, index) => item.key}
renderItem={(itemData) => (
<TouchableOpacity
onPress={onDelete.bind(itemData.item.key)}
activeOpacity={0.2}
>
<Text style={styles.listData}>{itemData.item.value}</Text>
{console.log(itemData.item.key)}
</TouchableOpacity>
)}
/>
);
}
this is my main component where i have my search input
import React from "react";
import { View, Text, StyleSheet, Pressable, TextInput } from "react-native";
export default function SearchBar(props) {
const onInputHandler = (value) => {
props.setCount(value);
};
return (
<View style={styles.searchBox}>
<Pressable style={styles.submitBtn} title="Click Me !">
<Text>☀️</Text>
</Pressable>
<TextInput
style={styles.searchInput}
placeholder="Enter Goal"
onChangeText={onInputHandler}
/>
<Pressable
style={styles.submitBtn}
title="Click Me !"
onPress={props.submitHandler}
>
<Text>🔥🔥</Text>
</Pressable>
</View>
);
}
const styles = StyleSheet.create({
searchBox: {
flexDirection: "row",
justifyContent: "space-around",
},
searchInput: {
width: "90%",
textAlign: "center",
padding: 10,
// color: 'white',
borderRadius: 10,
borderWidth: 1,
marginHorizontal: 5,
},
submitBtn: {
color: "black",
justifyContent: "space-around",
padding: 10,
borderRadius: 10,
borderWidth: 1,
},
});
You have to return the filtered array from your onDelete function
const onDelete = (goalId) => {
props.setCourseGoal((currGoal) => {
return currGoal.filter((goal) => goal.key !== goalId);
});
};

How to change default value and update with new value in TextInput in react native

How to update value of textinput in react native. I'm making notes taking app in which I get value from asynchoronus storage. And I want to edit that note value which I take as a default value. I want to update value in storage using textinput. My code is below. Please give a proper answer. Thank You.
import React, { useState } from 'react';
import { StyleSheet, Text, View,TextInput } from 'react-native';
import { FAB,IconButton } from 'react-native-paper';
import Header from './Header.js';
import AsyncStorage from '#react-native-community/async-storage';
export default function EditNotes({navigation}) {
const [noteTitle, setNoteTitle] = useState('')
const [noteDescription, setNoteDescription] = useState('')
const [noteTitlenew, setNoteTitlenew] = useState('')
const [noteDescriptionnew, setNoteDescriptionnew] = useState('')
getValueFunction = () => {
//function to get the value from AsyncStorage
AsyncStorage.getItem('onetitle').then(value =>
//AsyncStorage returns a promise so adding a callback to get the value
setNoteTitle(value)
);
AsyncStorage.getItem('onedesc').then(value =>
//AsyncStorage returns a promise so adding a callback to get the value
setNoteDescription(value)
);
};
return (
<>
<Header titleText = 'Edit Note' />
<View style={styles.container}>
{getValueFunction()}
<TextInput
placeholder = "Add Note Title here"
defaultValue = {noteTitle}
value = {noteTitlenew}
onChangeText = {setNoteTitlenew}
style = {styles.title}
/>
<TextInput
placeholder = "Add Note Description"
defaultValue = {noteDescription}
value = {noteDescriptionnew}
onChangeText = {setNoteDescriptionnew}
multiline={true}
style={styles.text}
scrollEnabled={true}
returnKeyLabel='done'
blurOnSubmit={true}
/>
<FAB
style={styles.fab}
small
icon='check'
/>
</View>
</>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
paddingTop:20,
paddingHorizontal:10
},
title:{
fontSize:24,
marginBottom:16,
borderWidth:1,
padding:15
},
text: {
fontSize:16,
borderWidth:1,
padding:15
},
fab:{
position:'absolute',
margin:20,
right:20,
bottom:0,
}
});
You do not need to use 2 separate states for default and value, instead, you can achieve the desired result by providing a single state for value and default value. Please update your code to the following
import React, { useState } from 'react';
import { StyleSheet, Text, View,TextInput } from 'react-native';
import { FAB,IconButton } from 'react-native-paper';
import Header from './Header.js';
import AsyncStorage from '#react-native-community/async-storage';
export default function EditNotes({navigation}) {
const [noteTitle, setNoteTitle] = useState('')
const [noteDescription, setNoteDescription] = useState('')
getValueFunction = () => {
//function to get the value from AsyncStorage
AsyncStorage.getItem('onetitle').then(value =>
//AsyncStorage returns a promise so adding a callback to get the value
setNoteTitle(value)
);
AsyncStorage.getItem('onedesc').then(value =>
//AsyncStorage returns a promise so adding a callback to get the value
setNoteDescription(value)
);
};
return (
<>
<Header titleText = 'Edit Note' />
<View style={styles.container}>
{getValueFunction()}
<TextInput
placeholder = "Add Note Title here"
defaultValue = {noteTitle}
value = {noteTitle}
onChangeText = {setNoteTitle}
style = {styles.title}
/>
<TextInput
placeholder = "Add Note Description"
defaultValue = {noteDescription}
value = {noteDescription}
onChangeText = {setNoteDescription}
multiline={true}
style={styles.text}
scrollEnabled={true}
returnKeyLabel='done'
blurOnSubmit={true}
/>
<FAB
style={styles.fab}
small
icon='check'
/>
</View>
</>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
paddingTop:20,
paddingHorizontal:10
},
title:{
fontSize:24,
marginBottom:16,
borderWidth:1,
padding:15
},
text: {
fontSize:16,
borderWidth:1,
padding:15
},
fab:{
position:'absolute',
margin:20,
right:20,
bottom:0,
}
});
Before you use react native carefully read the react native documentation.
About your code u don't want to need two state for updated and initial value, and you can pass the default value you in the useState and call it.

Categories

Resources