Set Hook in React Native - javascript

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

Related

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();
});
};

Ways to stop re-rendering when a state is changed ? (React Native)

Let me summarize a lil bit, what I'm trying to do is when the news is clicked, a modal (in this case I used a library: react-native-modalize https://github.com/jeremybarbet/react-native-modalize) is presented with the respective details of the clicked news
In order for the content inside the modal to be dynamic, I used states to store the details, so whenever a click is registered on the news, a series of details is passed thru function parameters and store in the respective state
THE PROBLEM is that whenever a state on the top level is changed the whole component refresh itself, and it's causing problem like:
Scenario 1: when the user scroll until the end of the scroll view and pressed on one of the news, modal is brought up and because the state is being changed, the whole app refreshes and the scroll view jumps back to the top.
app.js
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { useRef, useState, useEffect } from 'react';
import { AppLoading } from 'expo'
import { StyleSheet, Text, View, FlatList, SafeAreaView, ScrollView, Image, TouchableOpacity } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import { Modalize } from 'react-native-modalize';
import { Ionicons } from '#expo/vector-icons';
import { render } from 'react-dom';
import Header from './components/Header';
import NuaDaily from './components/Daily';
import Content from './components/Content';
import moment from "moment";
const HomeStackScreen = () => {
const [title, setTitle] = useState([])
const [author, setAuthor] = useState([])
const [publication, setPublication] = useState([])
const [imageUrl, setImageUrl] = useState([])
const [summary, setSummary] = useState([])
const modalizeRef = useRef(null);
const onOpen = (title, author, publication, imageUrl, summary) => {
modalizeRef.current?.open();
setTitle(title)
setAuthor(author)
setPublication(publication)
setImageUrl(imageUrl)
setSummary(summary)
};
return (
<>
<SafeAreaView style={styles.container}>
<ScrollView style={styles.scrollView}>
<View style={styles.container}>
<Header />
<NuaDaily modalize={onOpen} style={styles.nuadaily} />
<Content modalize={onOpen} />
</View>
</ScrollView>
</SafeAreaView>
<Modalize snapPoint={650} modalTopOffset={10} ref={modalizeRef} style={{ width: '100%', alignItems: 'center', justifyContent: 'center', padding: 20 }}>
<View style={{padding: 20}}>
<Image
style={{width: 350, height: 200, zIndex: 1000, borderRadius: 8, marginTop: 10}}
source={{ uri: `${imageUrl}` }}
/>
<Text style={styles.modalTitle}>{title}</Text>
<View style={styles.detailsBar}>
<Text style={styles.modalAuthor}>{author}</Text>
<Text style={styles.modalPublication}>{moment(publication).format("MM-DD-YYYY")}</Text>
</View>
<Text style={styles.modalSummary}>{summary}</Text>
</View>
</Modalize>
</>
)
}
const Tab = createBottomTabNavigator();
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator
tabBarOptions={
{
activeTintColor: '#00B2FF',
inactiveTintColor: 'gray',
showLabel: false,
style: { height: 60, borderRadius: 0, backgroundColor: 'rgba(255, 255, 255, 0.85)'}
}
}
showLabel = {false}
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {
if (route.name === 'Home') {
return <HomeIcon />
}
},
})}
>
<Tab.Screen name="Home"
component={
HomeStackScreen
} />
</Tab.Navigator>
</NavigationContainer>
);
}
});
Daily (index.js) (imported on app.js)
import React from 'react';
import { useState, useEffect } from 'react';
import {View, Text, FlatList, Image, ImageBackground, ScrollView, SafeAreaView, TouchableOpacity} from 'react-native';
import axios from 'axios';
import moment from "moment";
import * as Font from 'expo-font';
import AppLoading from 'expo-app-loading';
import { useFonts } from 'expo-font';
import styles from './style';
import Dot from '../../assets/images/dot.svg';
const nuaDaily = ( props ) => {
const Item = ({ title, author, publication, imageUrl, summary }) => (
<View style={styles.item}>
<TouchableOpacity onPress={()=>props.modalize(title, author, publication, imageUrl, summary)}>
<Image
style={{width: 210, height: 200, zIndex: 1000, borderRadius: 8, marginTop: 10}}
source={{ uri: `${imageUrl}` }}
/>
<Text style={ [styles.title, {fontFamily: 'Poppins'}]}>{title}</Text>
<View style={styles.bottomBar}>
<Text style={styles.author}>{author}</Text>
<Text style={styles.publication}>{moment(publication).format("MM-DD-YYYY hh:mm")}</Text>
</View>
</TouchableOpacity>
</View>
);
const renderItem = ({ item }) => {
if(moment(item.publication).isSame(moment(), 'day')){
return <Item title={item.title} author={item.newsSite} publication={item.publishedAt} imageUrl={item.imageUrl} summary={item.summary} />
}else{
// return <Item title={item.title} author={item.newsSite} publication={item.publishedAt} imageUrl={item.imageUrl} summary={item.summary} />
}
};
const [data, setData] = useState([])
useEffect(() => {
axios.get(APIURL)
.then((res) => {
setData(res.data)
})
.catch((err) => {
console.log(`error calling API ${err}`)
})
},[])
return (
<View style={styles.container}>
<View style={styles.containerTitle}>
<Dot style={styles.dot} />
<Text style={ [styles.PrimaryText , {fontFamily: 'Quicksand'}]}>NUA Daily</Text>
</View>
<FlatList
showsHorizontalScrollIndicator={false}
horizontal={true}
data={data}
renderItem={renderItem}
style={styles.flatList}
/>
</View>
)
}
export default nuaDaily;
Demo of the problem (Scenario 1)

Not sure how to map variable to show in app

Here's the function-
const setLoading = (value) => {
const messages = dashboards.data.message.filter((item) => {
const title = item.dashboardTitle || item.dashboardName;
return title.toLowerCase().startsWith(value.toLowerCase());
});
setFiltered(messages);
console.log(filtered);
};
I want to display the variable 'messages' separately in my app, how would I do that? 'messages' variable needs to be displayed within the default react native 'Text' component. I have written down 'messages' below within Text component but currently it's not displaying anything (since it is within function) -
import React, { useState, useEffect, useReducer } from 'react';
import { View, Text, StyleSheet, FlatList, ActivityIndicator, Keyboard} from 'react-native';
import { Searchbar } from 'react-native-paper';
import { theme } from '../theme';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
import { TouchableOpacity } from 'react-native-gesture-handler';
import { apiStateReducer } from '../reducers/ApiStateReducer';
import CognitensorEndpoints from '../services/network/CognitensorEndpoints';
import DefaultView from '../components/default/DefaultView';
import DashboardListCard from '../components/DashboardListCard';
const AppHeader = ({
scene,
previous,
navigation,
searchIconVisible = false,
}) => {
const [dashboards, dispatchDashboards] = useReducer(apiStateReducer, {
data: [],
isLoading: true,
isError: false,
});
const [filtered, setFiltered] = useState([]);
const setLoading = (value) => {
const messages = dashboards.data.message.filter((item) => {
const title = item.dashboardTitle || item.dashboardName;
return title.toLowerCase().startsWith(value.toLowerCase());
});
setFiltered(messages);
console.log(filtered);
};
const dropShadowStyle = styles.dropShadow;
const toggleSearchVisibility = () => {
navigation.navigate('Search');
};
useEffect(() => {
CognitensorEndpoints.getDashboardList({
dispatchReducer: dispatchDashboards,
});
}, []);
return (
<>
<View style={styles.header}>
<View style={styles.headerLeftIcon}>
<TouchableOpacity onPress={navigation.pop}>
{previous ? (
<MaterialIcons
name="chevron-left"
size={24}
style={styles.visible}
/>
) : (
<MaterialIcons
name="chevron-left"
size={24}
style={styles.invisible}
/>
)}
</TouchableOpacity>
</View>
<Text style={styles.headerText}>
{messages}
</Text>
<View style={styles.headerRightIconContainer}>
{searchIconVisible ? (
<TouchableOpacity
style={[styles.headerRightIcon, dropShadowStyle]}
onPress={toggleSearchVisibility}>
<MaterialIcons name="search" size={24} style={styles.visible} />
</TouchableOpacity>
) : (
<View style={styles.invisible} />
)}
</View>
</View>
</>
);
};
If your messages variable is an array you can map it
{messages.map((message, key)=>(
<Text style={styles.headerText}>
{message.dashboardName}
</Text>
))}
Since your messages variable is stored in 'filtered' state, you can map it by doing this:
{filtered.map((item, index) => <Text key={index}>{item.dashboardName}<Text>)}

Can't set state in js react-native

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

prevent backhandler from minimizing the app

how can I prevent the app from minimizing / exiting when pushing back button on my device?
Im trying to assign "browsers back" functionality when pressing back button on my device, heres my code:
import 'react-native-get-random-values';
import React, { useState, useRef, Component, useEffect } from 'react'
import {
Alert,
SafeAreaView,
StyleSheet,
StatusBar,
View,
Text,
ScrollView,
BackHandler,
RefreshControl
} from 'react-native'
import WebView from 'react-native-webview'
import Icon from 'react-native-vector-icons/FontAwesome';
import { Button } from 'react-native-elements';
const App = () => {
function backButtonHandler(){}
function refreshHandler(){
if (webviewRef.current) webviewRef.current.reload()
}
useEffect(() => {
BackHandler.addEventListener("hardwareBackPress", backButtonHandler);
return () => {
BackHandler.removeEventListener("hardwareBackPress", backButtonHandler);
};
}, [backButtonHandler]);
let jscode = `window.onscroll=function(){window.ReactNativeWebView.postMessage(document.documentElement.scrollTop||document.body.scrollTop)}`;
const [canGoBack, setCanGoBack] = useState(false)
const [currentUrl, setCurrentUrl] = useState('')
const [refreshing, setRefreshing] = useState(false);
const [scrollviewState, setEnableRefresh] = useState(false);
const webviewRef = useRef(null)
const scrollviewRef = useRef(false)
backButtonHandler = () => {
if (webviewRef.current) webviewRef.current.goBack()
}
return (
<>
<StatusBar barStyle='dark-content' />
<SafeAreaView style={styles.flexContainer}>
<ScrollView
contentContainerStyle={styles.flexContainer}
refreshControl={
<RefreshControl refreshing={false} onRefresh={refreshHandler} ref={scrollviewRef} enabled={ (scrollviewState) ? true : false } />
}>
<WebView
source={{ uri: 'https://youtube.com' }}
startInLoadingState={true}
ref={webviewRef}
onNavigationStateChange={navState => {
setCanGoBack(navState.canGoBack)
setCurrentUrl(navState.url)
}}
injectedJavaScript={jscode}
onMessage={(event)=>{
let message = event.nativeEvent.data;
let num = parseInt(message);
if(num==0){setEnableRefresh(true)}
else{setEnableRefresh(false)}
}}
/>
</ScrollView>
<View style={styles.tabBarContainer}>
<Button onPress={backButtonHandler}
icon={
<Icon
name="arrow-left"
size={15}
color="white"
/>
}
containerStyle={styles.buttonx}
title="Back"
/>
</View>
</SafeAreaView>
</>
)
}
const styles = StyleSheet.create({
flexContainer: {
flex: 1
},
tabBarContainer: {
flexDirection: 'row',
justifyContent: 'space-around',
backgroundColor: 'orange'
},
buttonx: {
backgroundColor:'blue',
width:'100%'
}
})
export default App
my problem is when I press the back button on my device, it does call backButtonHandler function and my webview navigates back, but at the same time the app minimizes too.. is there a way to prevent this?
change your backButtonHandler Method to just return true, when your backHandler Method does return true, it actually does nothing onPress Back button :
backButtonHandler = () => {
return true;
}

Categories

Resources