Multiple Input Text handle in object and array in react native - javascript

This is my code ....
react native
Multiple Input Text handle in object and array in react native...
Is it possible to share your code? Share the entire component where you have these groups of 5 inputs. You can just copy and paste it inside your question body. That way I can help you better
App.js
import {
StyleSheet,
Pressable,
View,
} from 'react-native';
import {
AntDesign,
FontAwesome
} from '#expo/vector-icons';
import { useState } from 'react';
import AddStudentProfile from './Pages/AddStudentProfile';
import StudentList from './Pages/StudentList';
export default function App() {
const [iconColor, setIconColor] = useState(['#ab09bf', '#A9A9A9']);
const [multiValues, setMultiValues] = useState([]);
const [screen, setScreen] = useState(<StudentList stuList={multiValues} />);
function changeIconColor(pressCheck) {
if (pressCheck) {
setIconColor([
'#ab09bf',
'#A9A9A9'
]
);
}
else {
setIconColor([
'#A9A9A9',
'#ab09bf'
]
);
}
}
// const [iconChangableColor, setIconChangableColor] = useState('#A9A9A9');
function changeScreen(scr) {
setScreen(
// < AddStudentProfile />
scr
);
// setIconChangableColor('#ab09bf');
// console.log(multiValues)
changeIconColor(true)
}
function appendData(inp, onsrcChange) {
setScreen(
// < AddStudentProfile />
onsrcChange
);
setMultiValues([
...multiValues,
inp]);
console.log(multiValues)
}
return (
< View style={styles.container} >
<View style={{ flex: 9 }}>{screen}
</View>
<View >
<View style={styles.bottomIconContainer}>
<Pressable onPress={() => [changeScreen(<StudentList />), changeIconColor(true)]}
android_ripple={{ color: 'black' }}>
<View style={styles.bottomIconInnerContainer}>
<FontAwesome
name="list-ul"
size={35}
color={iconColor[0]} />
</View></Pressable>
<Pressable onPress={() => [changeScreen(<AddStudentProfile onAppendData={appendData} returnToProfile={changeScreen} />), changeIconColor(false)]}
android_ripple={{ color: 'black' }}>
<View style={styles.bottomIconInnerContainer}>
<AntDesign name="adduser"
size={35}
color={iconColor[1]}
/></View></Pressable></View>
</View>
</View >
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
},
bottomIconContainer: {
flexDirection: 'row',
justifyContent: 'space-around',
alignItems: 'center',
},
bottomIconInnerContainer: {
marginVertical: 20,
marginHorizontal: 80
}
});
AddStudentProfile.js
import {
Text,
TextInput,
ImageBackground,
View,
Button,
ScrollView,
StatusBar,
StyleSheet
} from "react-native";
import { useState } from "react";
import { AntDesign } from '#expo/vector-icons';
import PrimaryButton from "../Componenets/PrimaryButton";
import ColorCode from "../Componenets/ColorCode.js";
export default function AddStudentProfile({ returnToProfile, onAppendData }) {
const [values, setValues] = useState({});
function inputHandler(name, value) {
setValues({
...values,
[name]: value
})
}
function inpValues(srcChange) {
onAppendData(values, srcChange)
console.log(values)
}
return (
<ScrollView>
<View style={styles.screenContainer}>
<View>
<Text style={styles.textContainer}>
Add Student Profile
</Text>
</View>
<View style={styles.iconOutterContainer}>
<View style={styles.iconContainer}>
<AntDesign
name="user"
size={80}
color='white'
/>
</View>
</View>
<View style={{ alignItems: 'center' }}>
<TextInput
style={styles.inputTextContainer}
placeholder="name"
placeholderTextColor={ColorCode.placeHolder}
onChangeText={(val) => inputHandler('sname', val)}
/>
<TextInput
style={styles.inputTextContainer}
placeholder="roll no"
placeholderTextColor={ColorCode.placeHolder}
onChangeText={(val) => inputHandler('rno', val)}
/>
<TextInput
style={styles.inputTextContainer}
placeholder="department"
placeholderTextColor={ColorCode.placeHolder}
onChangeText={(val) => inputHandler('dep', val)}
/>
<TextInput
style={styles.inputTextContainer}
placeholder="e-mail"
placeholderTextColor={ColorCode.placeHolder}
onChangeText={(val) => inputHandler('mail', val)}
/>
<TextInput
style={styles.inputTextContainer}
placeholder="Phone no"
placeholderTextColor={ColorCode.placeHolder}
onChangeText={(val) => inputHandler('phno', val)}
/>
</View>
<PrimaryButton
onreturnToProfile={returnToProfile}
inputValues={inpValues}
changeColor='#8a0896'
>Save</PrimaryButton>
</View>
</ScrollView>
);
}
const styles = StyleSheet.create({
iconContainer: {
height: 100,
width: 100,
borderRadius: 100,
backgroundColor: '#ab09bf',
alignItems: 'center',
justifyContent: 'center'
},
textContainer: {
marginVertical: 10,
textAlign: 'center',
fontSize: 20,
},
screenContainer: {
marginTop: StatusBar.currentHeight,
flex: 1,
padding: 20
},
iconOutterContainer: {
alignItems: 'center'
},
inputOutterContainer: {
padding: 10,
marginHorizontal: 5
},
inputTextContainer: {
padding: 10,
backgroundColor: '#fff',
marginVertical: 10,
width: '95%',
fontSize: 19,
elevation: 5,
borderRadius: 6,
shadowColor: '#ab09bf',
color: '#ab09bf'
},
buttonOutterContainer: {
width: '30%',
marginHorizontal: 10,
fontSize: 20
},
buttonInnerContainer: { fontSize: 23 }
});
PrimaryButton.js
import {
View,
Text,
Pressable,
StyleSheet
} from 'react-native';
import StudentList from '../Pages/StudentList';
export default function PrimaryButton({ children, inputValues, onreturnToProfile }) {
function pressHandler() {
//onreturnToProfile();
inputValues(<StudentList />)
}
return (
< View style={{ alignItems: 'center', marginTop: 15 }
}>
<View
style={styles.textOutterContainer}
>
<Pressable
onPress={pressHandler}
android_ripple={{ color: 'white' }}
>
<Text style={styles.textContainer}>{children}</Text>
</Pressable>
</View>
</View >
);
}
const styles = StyleSheet.create({
textContainer: {
fontSize: 23,
color: 'white',
textAlign: 'center'
},
textOutterContainer: {
backgroundColor: '#8a0896',
borderRadius: 22,
width: '20%',
height: 40,
alignItems: 'center',
justifyContent: 'center'
}
})

I have gone through your code and it seems to be right even though a bit complicated. What is the issue you are facing?
You are adding a set of student info(5 fields) on a button press to a parent component state. You are appending it to an empty array. Ideally, you should get something like the below. What seems to be the problem? Please explain.
multiValues = [
{
'sname': 'some sname',
'rno': 'some rno',
'dep': 'some dep',
'mail': 'some mail',
'phno': 'some phno'
},
{
'sname': 'some sname',
'rno': 'some rno',
'dep': 'some dep',
'mail': 'some mail',
'phno': 'some phno'
},
{
'sname': 'some sname',
'rno': 'some rno',
'dep': 'some dep',
'mail': 'some mail',
'phno': 'some phno'
},
{
'sname': 'some sname',
'rno': 'some rno',
'dep': 'some dep',
'mail': 'some mail',
'phno': 'some phno'
},
]
Will update this answer depending on your response so that it might be of help to someone else.

Related

Undefined is not a function (near '... map ...')

When I tap in the Pressable element in the JSX I get the error : Undefined is not a function (near '... wines.map ...'). The log says it's coming from the wines.map loop in the JSX. I'm unsure on what could be wrong with how I'm trying to change the data in the toggle function or how I set the default useState array object. The code is supposed to toggle between two different kind of images for each button independently.
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* #format
* #flow strict-local
*/
import 'react-native-gesture-handler';
import React, {useState} from 'react';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import {
SafeAreaView,
StyleSheet,
ScrollView,
View,
Text,
StatusBar,
ImageBackground,
Image,
TextInput,
Button,
TouchableNativeFeedback,
TouchableWithoutFeedback,
TouchableOpacity,
TouchableHighlight,
FlatList,
Pressable,
RecyclerViewBackedScrollViewComponent
} from 'react-native';
import { Immersive } from 'react-native-immersive';
const fullWine = require('../images/selected-wine.png');
const emptyWine = require('../images/empty-wine-icon.png');
const WineList = () => {
Immersive.on()
Immersive.setImmersive(true)
const [wines, setWines] = useState([
{
name: "2018 Prezzo",
info: "What dsbetter way to spend a lazy afternoon than sipping away on this wine.",
imageUrl: emptyWine
},
{
name: "2018 Coqueta",
info: "A litstle flirty wine.",
imageUrl: emptyWine
}
])
function toggle(pressedWine){
let oldWines = [...wines]
let newWines = oldWines.map((wine) => {
if(wine === pressedWine){
if(wine.imageUrl == emptyWine){
wine.imageUrl = fullWine;
} else {
wine.imageUrl = emptyWine;
}
}
return wine;
});
setWines({newWines});
// setWines({newWines});
}
return (
<View style={{flex:1}}>
<ScrollView style={styles.scrollView}>
<View style={styles.headerMessage}>
<Text style={styles.headerMessageText}>Select your wines for tasting</Text>
</View>
<View style={[styles.wineListWrapper]}>
{ wines.map((wine, index) => {
return(
<View key={index} style={[styles.item]}>
<Image source={require('../images/Peresozo2018.png')} style={[styles.bottle]} />
<View style={[styles.infoWrapper]}>
<Text style={[styles.itemTitle]}>{wine.name}</Text>
<Text style={[styles.itemInfo]}>
{wine.info}
</Text>
</View>
<Pressable onPress={ (wine) => toggle(wine) } style={[styles.wineIcon]}>
<Image source={wine.imageUrl} />
</Pressable>
</View>
)
})}
</View>
</ScrollView>
<TouchableOpacity onPress={() => alert('yo') } style={[styles.footerButton]}>
<Text style={[styles.footerText]}>Start Tasting</Text>
</TouchableOpacity>
</View>
)
}
const styles = StyleSheet.create({
footerButton:{
flex:1,
justifyContent: 'flex-end',
alignContent:'center',
alignItems:'center',
backgroundColor:'white',
paddingTop:90
},
footerText:{
fontFamily: 'Charm-Regular',
fontSize:40,
color:'#624124'
},
item:{
flex:1,
flexDirection: 'row',
justifyContent: 'space-between',
padding: 10
},
infoWrapper:{
flex:0.7,
flexWrap: 'wrap',
flexDirection: 'row',
padding:10,
alignSelf:'flex-start',
justifyContent: 'space-between',
marginTop: -30,
marginLeft:1
},
itemTitle:{
color:'white',
fontFamily: 'Charm-Regular',
fontSize: 40,
},
itemInfo:{
color:'white',
fontSize: 20,
},
wineIcon:{
padding:5,
flex:0.15
},
wineListWrapper:{
marginLeft: 10,
marginTop: 40
},
bottle:{
marginLeft: 2,
width: 80,
height: 250,
resizeMode: 'contain',
},
scrollView:{
backgroundColor: '#4B4239',
},
headerMessage:{
backgroundColor: 'white',
flex: 1,
alignItems: 'center',
alignContent: 'center',
justifyContent: 'center',
flexDirection: 'column',
alignSelf: 'center',
width:400,
borderRadius: 4,
padding: 0,
marginTop: 10
},
headerMessageText:{
color: '#4B4239',
textAlign: 'center',
fontSize: 30,
fontFamily: 'Charm-Regular',
lineHeight: 50
}
})
export default WineList
The issue is that you're setting an object into the wines state when updating it:
setWines({ newWines });
Since the value of the state is an array, you probably meant:
setWines(newWines);
Additionally, the parameter passed to the onPress callback is not the wine object, but a PressEvent. As a result, you're shadowing the wine variable from the .map() with the event object from the callback's parameter.
You probably meant to pass the wine from the loop to toggle instead, so just remove the (wine) => parameter.
<Pressable onPress={() => toggle(wine)} style={[styles.wineIcon]}>
<Image source={wine.imageUrl} />
</Pressable>

React-native app to many re-renders & function keeps running on state change

I get an error for to many re-renders. It seems that the compareDate function gets run every time a state updates. The compareDate only has to be run when the app opens to check if it's a new day since last login so that it can reset the program by doing addWater(-dailyGoal). Does anyone know how I can make it only run once on opening the app?
import { StatusBar } from 'expo-status-bar';
import React, { useState } from 'react';
import {
StyleSheet,
Text,
View,
SafeAreaView,
Alert,
TouchableOpacity,
Keyboard,
TextInput,
} from 'react-native';
import AsyncStorage from '#react-native-community/async-storage';
import { FontAwesomeIcon } from '#fortawesome/react-native-fontawesome';
import { faTint, faCog, faTimes } from '#fortawesome/free-solid-svg-icons';
export default function App() {
// set vars
const [waterDrank, setWaterDrank] = useState(0);
const [menuOpen, setmenuOpen] = useState(false);
const [dailyGoal, setDailyGoal] = useState(3700);
const [bottle, setBottle] = useState(250);
const [dailyGoalSettings, onChangeDailyGoalSettings] = useState(
`${dailyGoal}`
);
const [bottleSettings, onChangeBottleSettings] = useState(`${bottle}`);
// Async storage
const storeWater = async (value) => {
try {
await AsyncStorage.setItem('storedWater', value);
} catch (e) {
// saving error
}
};
const getStoredWater = async () => {
try {
const value = await AsyncStorage.getItem('storedWater');
if (value !== null && !isNaN(value)) {
setWaterDrank(parseInt(value));
}
} catch (e) {
// error reading value
}
};
// init stored water data
getStoredWater();
// store settings
const storeSettings = async (daily, bottle) => {
try {
await AsyncStorage.setItem('dailyGoalSetting', daily);
await AsyncStorage.setItem('bottleSetting', bottle);
} catch (e) {
// saving error
}
};
const getStoredSettings = async () => {
try {
const valueDailyGoalSetting = await AsyncStorage.getItem(
'dailyGoalSetting'
);
const valueBottleSetting = await AsyncStorage.getItem(
'bottleSetting'
);
if (
valueDailyGoalSetting !== null &&
!isNaN(valueDailyGoalSetting) &&
valueBottleSetting !== null &&
!isNaN(valueBottleSetting)
) {
setDailyGoal(valueDailyGoalSetting);
setBottle(valueBottleSetting);
}
} catch (e) {
// error reading value
}
};
// init stored settings data
getStoredSettings();
const addWater = (amount) => {
amount = parseInt(amount);
if (!isNaN(amount)) {
if (waterDrank + amount >= dailyGoal) {
setWaterDrank(dailyGoal);
storeWater(`${dailyGoal}`);
} else if (waterDrank + amount <= 0) {
setWaterDrank(0);
storeWater(`0`);
} else {
setWaterDrank(waterDrank + amount);
storeWater(`${waterDrank + amount}`);
}
} else {
setWaterDrank(waterDrank + 0);
storeWater(`${waterDrank + 0}`);
}
};
const compareDate = () => {
const firstDateIsPastDayComparedToSecond = (firstDate, secondDate) =>
firstDate.setHours(0, 0, 0, 0) - secondDate.setHours(0, 0, 0, 0) <
0;
const currentDate = new Date();
const storedDate = new Date(currentDate);
storedDate.setDate(storedDate.getDate() - 1);
// is the first date in the past
if (firstDateIsPastDayComparedToSecond(storedDate, currentDate)) {
addWater(-dailyGoal);
}
};
compareDate();
const settingsToggle = () => {
setmenuOpen(!menuOpen);
Keyboard.dismiss();
};
const settingsSave = () => {
storeSettings(dailyGoalSettings, bottleSettings);
getStoredSettings();
settingsToggle();
};
return (
<View style={styles.body}>
{/* settings */}
<View
style={[
styles.settingsMenu,
{
display: `${menuOpen ? 'block' : 'none'}`,
},
]}
>
<SafeAreaView onPress={() => Keyboard.dismiss()}>
<TouchableOpacity
style={styles.settingsButton}
onPress={() => settingsToggle()}
>
<FontAwesomeIcon
icon={faTimes}
color={'black'}
size={24}
/>
</TouchableOpacity>
<View style={{ paddingHorizontal: 20 }}>
<Text style={styles.settingsText}>
Daily water goal in ml
</Text>
<TextInput
style={styles.settingsInput}
onChangeText={(text) =>
onChangeDailyGoalSettings(text)
}
value={dailyGoalSettings}
keyboardType={'number-pad'}
/>
<Text style={styles.settingsText}>
Amount of a bottle in ml
</Text>
<TextInput
style={styles.settingsInput}
onChangeText={(text) =>
onChangeBottleSettings(text)
}
value={bottleSettings}
keyboardType={'number-pad'}
/>
<TouchableOpacity
style={styles.settingsSave}
onPress={() => settingsSave()}
>
<Text
style={{
alignSelf: 'center',
color: '#fff',
fontWeight: 'bold',
}}
>
Save
</Text>
</TouchableOpacity>
</View>
</SafeAreaView>
</View>
{/* main content */}
<SafeAreaView style={styles.container}>
<TouchableOpacity
style={styles.settingsButton}
onPress={() => settingsToggle()}
>
<FontAwesomeIcon icon={faCog} color={'white'} size={24} />
</TouchableOpacity>
<View style={styles.wrapper}>
<Text style={styles.textWaterLeft}>
{dailyGoal - waterDrank}
<Text style={styles.textWaterLeftMeasurement}>ml</Text>
</Text>
<Text style={styles.titleText}>
Left to hit your daily goal!
</Text>
</View>
<View style={styles.wrapper}>
<View style={styles.buttonContainer}>
<TouchableOpacity
style={[
styles.button,
{
backgroundColor: `${
waterDrank >= dailyGoal
? '#4DAC5F'
: '#0064ED'
}`,
},
]}
onPress={() => addWater(-bottle)}
>
<Text style={styles.buttonText}>
-
<FontAwesomeIcon
icon={faTint}
color={'white'}
/>
</Text>
</TouchableOpacity>
<TouchableOpacity
style={[
styles.button,
{
backgroundColor: `${
waterDrank >= dailyGoal
? '#4DAC5F'
: '#0064ED'
}`,
},
]}
onPress={() =>
Alert.prompt(
'How much water did you drink?',
'',
[
{
text: 'OK',
onPress: (amount) =>
addWater(amount),
},
]
)
}
>
<Text style={styles.buttonText}>+</Text>
</TouchableOpacity>
<TouchableOpacity
style={[
styles.button,
{
backgroundColor: `${
waterDrank >= dailyGoal
? '#4DAC5F'
: '#0064ED'
}`,
},
]}
onPress={() => addWater(bottle)}
>
<Text style={styles.buttonText}>
+
<FontAwesomeIcon
icon={faTint}
color={'white'}
/>
</Text>
</TouchableOpacity>
</View>
</View>
<StatusBar style="auto" barStyle="dark-content" />
</SafeAreaView>
<View
style={[
styles.indicator,
{
height: `${Math.floor(
(100 / dailyGoal) * waterDrank
)}%`,
backgroundColor: `${
waterDrank >= dailyGoal ? '#51E66E' : '#1782FF'
}`,
},
]}
></View>
</View>
);
}
const styles = StyleSheet.create({
body: {
flex: 1,
backgroundColor: '#152940',
},
container: {
flex: 1,
},
wrapper: {
flex: 1,
justifyContent: 'flex-end',
alignItems: 'center',
},
indicator: {
position: 'absolute',
width: '100%',
bottom: 0,
zIndex: -1,
},
textWaterLeft: {
fontSize: 77,
color: '#fff',
fontWeight: 'bold',
},
textWaterLeftMeasurement: {
fontSize: 18,
fontWeight: 'normal',
color: '#fff',
marginTop: 200,
marginBottom: 10,
},
titleText: {
color: '#fff',
fontSize: 18,
marginBottom: 30,
},
buttonContainer: {
flexDirection: 'row',
justifyContent: 'space-between',
flexWrap: 'wrap',
},
button: {
flex: 1,
margin: 10,
backgroundColor: '#0064ED',
borderRadius: 10,
},
buttonText: {
textAlign: 'center',
color: '#fff',
margin: 20,
fontSize: 18,
},
settingsButton: {
height: 40,
width: 40,
alignSelf: 'flex-end',
zIndex: 2,
justifyContent: 'flex-end',
},
settingsMenu: {
position: 'absolute',
height: '100%',
width: '100%',
backgroundColor: '#fff',
zIndex: 200,
},
settingsText: {
marginTop: 30,
},
settingsInput: {
height: 40,
borderColor: 'gray',
borderWidth: 1,
paddingHorizontal: 20,
marginTop: 10,
},
settingsSave: {
marginTop: 30,
textAlign: 'center',
width: '100%',
padding: 15,
borderRadius: 10,
backgroundColor: '#0064ED',
},
});
Ciao, try to use useEffect hook like this:
import React, { useState, useEffect } from 'react';
...
useEffect(() => {
compareDate();
}, [])
In this way compareDate() will be triggered only once at component renders.

Unable to update state in react native component using onChangeText

I have been trying to update the email and password value on submitting the form
so that I can pass them in my login API parameters. But I have tried almost everything, the value of this.state won't just update. Every time I try to print the value in console log e.g: cosole.log(this.state.email), it prints empty string i.e the default value set previously.
Here is my code below:
login.js
import React, { Component } from 'react';
import { ThemeProvider, Button } from 'react-native-elements';
import BliszFloatingLabel from './BliszFloatingLabel'
import {
StyleSheet,
Text,
View,
Image,
TextInput,
Animated,
ImageBackground,
Linking
} from 'react-native';
const domain = 'http://1xx.xxx.xx.xxx:8000';
class Login extends Component {
state = {
email: '',
password: '',
}
LoginAPI = (e,p) => {
console.log(e, "####")
}
handleEmail = (text) => {
this.setState({ email: text })
}
handlePassword = (text) => {
this.setState({ password: text })
}
goToSignUpScreen=() =>{
this.props.navigation.navigate('SignUpScreen');
};
goToForgotPasswordScreen=() =>{
this.props.navigation.navigate('ForgotPasswordScreen');
};
render() {
return (
<View style={styles.container} >
<ImageBackground source={require('../bgrndlogin.jpeg')} style={styles.image} >
<View style={styles.heading}>
<Image style={styles.logo} source={require('../loginlogo.png')} />
<Text style={styles.logoText}>Login</Text>
<Text style={styles.logodesc}>Please Login to continue --></Text>
</View>
<View style={styles.form_container}>
<BliszFloatingLabel
label="Email Id"
value={this.state.email}
onChangeText = {this.handleEmail}
onBlur={this.handleBluremail}
/>
<BliszFloatingLabel
label="Password"
value={this.state.password}
onChangeText = {this.handlePassword}
onBlur={this.handleBlurpwd}
secureTextEntry={true}
/>
<ThemeProvider theme={theme}>
<Button buttonStyle={{
opacity: 0.6,
backgroundColor: '#CC2C24',
borderColor: 'white',
borderWidth: 1,
width: 200,
height: 50,
marginTop: 30,
marginLeft: '20%',
alignItems: 'center',
justifyContent: "center"
}}
title="Login"
type="outline"
onPress = {
() => this.LoginAPI(this.state.email, this.state.password)
}
/>
</ThemeProvider>
<Text style={{
marginTop: 70,
color: '#CC2C24',
fontSize: 16,
fontWeight: "bold"
}}
onPress={
this.goToForgotPasswordScreen
}>
Forgot Password?
</Text>
<Text style={{
marginTop: 20,
color: '#CC2C24',
fontSize: 16,
fontWeight: "bold"
}}
onPress={
this.goToSignUpScreen
}>
Don't have an Account?
</Text>
</View>
</ImageBackground>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
logo: {
width: 115,
height: 50,
},
logoText: {
color: 'white',
fontSize: 36,
fontWeight: "bold"
},
logodesc: {
color: '#CC2C24',
fontSize: 18,
fontWeight: "bold"
},
heading: {
flex: 3,
marginLeft:20,
marginTop:30
},
form_container: {
flex: 7,
marginLeft:20,
marginTop:30,
marginRight: 20,
},
image: {
flex: 1,
resizeMode: "cover",
justifyContent: "center"
},
});
const theme = {
Button: {
titleStyle: {
color: 'white',
fontWeight: "bold",
fontSize: 18
},
},
};
export default Login;
I have created a common form as below which I inherit everywhere :
BliszFloatingLabel.js
import React, { Component } from 'react';
import {
Text,
View,
TextInput,
Animated,
} from 'react-native';
class BliszFloatingLabel extends Component {
state = {
entry: '',
isFocused: false,
};
UNSAFE_componentWillMount() {
this._animatedIsFocused = new Animated.Value(0);
}
handleInputChange = (inputName, inputValue) => {
this.setState(state => ({
...state,
[inputName]: inputValue // <-- Put square brackets
}))
}
handleFocus = () => this.setState({ isFocused: true })
handleBlur = () => this.setState({ isFocused: true?this.state.entry!='' :true})
handleValueChange = (entry) => this.setState({ entry });
componentDidUpdate() {
Animated.timing(this._animatedIsFocused, {
toValue: this.state.isFocused ? 1 : 0,
duration: 200,
useNativeDriver: true,
}).start();
}
render() {
// console.log(this.state.entry)
const { label, ...props } = this.props;
const { isFocused } = this.state;
const labelStyle = {
position: 'absolute',
left: 0,
top: !isFocused ? 40 : 0,
fontSize: !isFocused ? 16 : 12,
color: 'white',
};
return (
<View style={{ paddingTop: 20,paddingBottom:20 }}>
<Text style={labelStyle}>
{label}
</Text>
<TextInput
{...props}
style={{
height: 50, fontSize: 16, color: 'white', borderBottomWidth: 1, borderBottomColor: "white"
}}
value={this.state.entry}
onChangeText={this.handleValueChange}
onFocus={this.handleFocus}
onBlur={this.handleBlur}
blurOnSubmit
/>
</View>
)
}
}
export default BliszFloatingLabel;
Instead of passing onChangeText like this onChangeText={this.handleValueChange} pass in a callback in BliszFloatingLabel and also in Login component.
onChangeText={(text)=>this.handleValueChange(text)}
Snack with the fixture.
https://snack.expo.io/#waheed25/d16fb3

List item for chat from Array inside array React Native

This is my code for Chat Box, the window where I have "In" and "Out" messages are appearing.
import React, { Component } from "react";
import {
StyleSheet,
Text,
View,
TouchableOpacity,
TextInput,
FlatList,
Platform,
AsyncStorage
} from "react-native";
import Tutor from "../image/krutika.jpg";
import {
Container,
Header,
Left,
Input,
Body,
Right,
Thumbnail,
Button
} from "native-base";
import FontAwesome from "react-native-vector-icons/FontAwesome";
import Ionicons from "react-native-vector-icons/Ionicons";
import Icon1 from "react-native-vector-icons/FontAwesome";
import axios from "axios";
export default class ChatBox extends Component {
static navigationOptions = {
header: null
};
state = {
group_msgs: [],
student_id: null
};
renderDate = date => {
return <Text style={styles.time}>{date}</Text>;
};
componentWillMount = () => {
this.loading();
const { navigation } = this.props;
groupName = navigation.getParam("groupName");
group_id = navigation.getParam("group_id");
};
loading = async () => {
const userid = await AsyncStorage.getItem("user_id");
this.state.student_id = userid;
try {
let { data } = await axios.get('https://www.qualpros.com/chat/imApi/getMessage?groupId=6&limit=10&start=0&userId=62').then(response => {
// console.log(response)
if (response.status == 200) {
this.setState({ group_msgs: response.data.response.message });
console.log(response.data.response)
} else {
}
});
} catch (err) {
console.log(err);
}
};
render() {
return (
<Container>
<Header style={{ backgroundColor: "#d91009" }}>
<Left style={{ flex: 1, flexDirection: "row" }}>
<TouchableOpacity
style={styles.backArrow}
onPress={() => this.props.navigation.navigate("ChatScreen")}
>
<FontAwesome name="angle-left" size={30} color="#fff" />
</TouchableOpacity>
<Thumbnail
source={Tutor}
style={{
marginLeft: 8,
width: 30,
height: 30,
borderRadius: 30 / 2
}}
/>
</Left>
<Body>
<Text
onPress={() => {
this.props.navigation.navigate("Groupmembers", {
group_id:group_id,
groupname:groupName,
});
}}
style={{
alignSelf: Platform.OS == "android" ? "center" : null,
fontSize: 17,
color: "#fff"
}}
>
{groupName}
</Text>
</Body>
<Right>
<Button
style={{ backgroundColor: "#d91009" }}
onPress={() => {
this.props.navigation.navigate("TutorCalender");
}}
>
<Icon1 active name="calendar" size={24} color="#FFF" />
</Button>
</Right>
</Header>
<View style={styles.container}>
<FlatList
style={styles.list}
data={this.state.group_msgs}
keyExtractor={item => {
return item.m_id;
}}
renderItem={message => {
console.log(item);
const item = message.item;
let inMessage = (item.sender === this.state.userid) ? 'in' : 'out';
let itemStyle = inMessage ? styles.itemIn : styles.itemOut;
return (
<View style={[styles.item, itemStyle]}>
<View style={[styles.balloon]}>
<Text>{item.message}</Text>
</View>
</View>
);
}}
/>
<View style={styles.footer}>
<View style={styles.inputContainer}>
<TextInput
style={styles.inputs}
placeholder="Write a message..."
underlineColorAndroid="transparent"
onChangeText={name_address => this.setState({ name_address })}
/>
</View>
{/* <TouchableOpacity style={styles.btnSend}>
<Ionicons name="md-send" size={36} color='#d91009' /> style={styles.iconSend} />
</TouchableOpacity> */}
</View>
</View>
</Container>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1
},
list: {
paddingHorizontal: 17
},
footer: {
flexDirection: "row",
height: 60,
backgroundColor: "#eeeeee",
paddingHorizontal: 10,
padding: 5
},
btnSend: {
//color: "#d91009",
width: 40,
height: 40,
borderRadius: 360,
alignItems: "center",
justifyContent: "center"
},
iconSend: {
width: 30,
height: 30,
alignSelf: "center"
},
inputContainer: {
borderBottomColor: "#F5FCFF",
backgroundColor: "#FFFFFF",
borderRadius: 30,
borderBottomWidth: 1,
height: 40,
flexDirection: "row",
alignItems: "center",
flex: 1,
marginRight: 10
},
inputs: {
height: 40,
marginLeft: 16,
borderBottomColor: "#FFFFFF",
flex: 1
},
balloon: {
maxWidth: 250,
padding: 15,
borderRadius: 20
},
itemIn: {
alignSelf: "flex-start",
backgroundColor: "#eeeeee"
},
itemOut: {
alignSelf: "flex-end",
backgroundColor: "#DCF8C5"
},
time: {
alignSelf: "flex-end",
margin: 15,
fontSize: 12,
color: "#808080"
},
item: {
marginVertical: 14,
flex: 1,
flexDirection: "row",
borderRadius: 300,
padding: 1
}
});
I am using axios to fetch the api, the api response is coming as an Array inside the array but nothing is coming on the screen.
I can get it with storing response upto message but then I can't have the loop on messages.
Please help.
Thanks in advance
When doing a GET request to the endpoint in your code the response looks as follows:
{
"status":{
"code":200,
"message":"Success"
},
"totalMessage":6,
"recentMessageId":228,
"response":[
...
]
}
Inside the response object there's an array of message objects so you can't use response.data.response.message when setting state. That part of your code needs to be:
this.setState({ group_msgs: response.data.response });
Now you should be able to iterate through the group_msgs object to get the message key value for each item in the array.
Also in the FlatList component you should have
keyExtractor={item => {
return item.message.m_id;
}}
Your renderItem seems to be wrong as well, see should be something like this:
renderItem={ ({item}) => {
let inMessage = (item.sender.usedId === this.state.userid) ? 'in' : 'out';
let itemStyle = inMessage ? styles.itemIn : styles.itemOut;
return (
<View style={[styles.item, itemStyle]}>
<View style={[styles.balloon]}>
<Text>{item.message.message}</Text>
</View>
</View>
);
}}
I strongly suggest you take a look at the structure of the response object since that's where you are failing at the moment.

how to get data according to position in react native

I am a beginner in React Native, below code is related to my Home page which has flat list and Video item in Row and now On Press I need data related to particular row... as we do in android we get data by position...
how to get data according to position in react native
I want to achieve something like this passing the position from listview to new activity
import React, { Component } from "react";
import {
Platform,
StyleSheet,
Text,
View,
Image,
TouchableOpacity,
FlatList
} from "react-native";
import Icon from "react-native-vector-icons/MaterialIcons";
import VideoItem from "../src/VideoItem";
import data from "../src/data.json";
import About from "./About";
type Props = {};
export default class Home extends Component {
render() {
// alert(data.kind);
return (
<View style={styles.container}>
<View style={styles.Nav}>
<Image
source={require("../src/Images/logo.jpg")}
style={{ width: 98, height: 22 }}
/>
<View style={styles.RightNav}>
<TouchableOpacity>
<Icon style={styles.NavItems} name="search" size={25} />
</TouchableOpacity>
<TouchableOpacity>
<Icon style={styles.NavItems} name="account-circle" size={25} />
</TouchableOpacity>
</View>
</View>
<View style={styles.body}>
{/* <VideoItem video={data.items[0]} /> */}
<FlatList
data={data.items}
renderItem={video => <VideoItem video={video.item} />}
keyExtractor={item => item.id}
ItemSeparatorComponent={() => (
<View style={{ height: 0.5, backgroundColor: "#E5E5E5" }} />
)}
/>
</View>
<View style={styles.tabBar}>
<TouchableOpacity style={styles.TabItems}>
<Icon name="home" size={25} />
<Text style={styles.TabTitle}>Home</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.TabItems}>
<Icon name="whatshot" size={25} />
<Text style={styles.TabTitle}>Trending</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.TabItems}>
<Icon name="subscriptions" size={25} />
<Text style={styles.TabTitle}>Subscriptions</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.TabItems}>
<Icon name="folder" size={25} />
<Text style={styles.TabTitle}>Library</Text>
</TouchableOpacity>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1
},
Nav: {
height: 50,
backgroundColor: "white",
elevation: 3,
flexDirection: "row",
alignItems: "center",
paddingHorizontal: 15,
justifyContent: "space-between"
},
RightNav: {
flexDirection: "row"
},
NavItems: {
marginLeft: 20
},
body: {
flex: 1
},
tabBar: {
backgroundColor: "white",
height: 60,
borderTopWidth: 0.5,
borderColor: "#E5E5E5",
justifyContent: "space-around",
flexDirection: "row"
},
TabItems: {
justifyContent: "center",
alignItems: "center"
},
TabTitle: {
fontSize: 11,
color: "#3c3c3c",
paddingTop: 4
}
});
import React, { Component } from "react";
import {
Platform,
StyleSheet,
Text,
View,
Image,
TouchableOpacity
} from "react-native";
import { Actions } from 'react-native-router-flux';
import Icon from "react-native-vector-icons/MaterialIcons";
import VideoComponent from "./VideoComponent ";
import About from "./About";
export default class VideoItem extends Component {
render() {
let video = this.props.video;
// alert(video.etag);
return (
<View style={styles.container}>
<TouchableOpacity onPress={ () => goToAbout()}>
<Image
source={{ uri: video.snippet.thumbnails.medium.url }}
style={{ height: 200 }}
/>
<View style={styles.Description} >
<Image source ={{uri:'https://randomuser.me/api/portraits/women/75.jpg'}} style={{width:50,height:50,borderRadius:25}}/>
<View style={styles.VideoDetails}>
<Text numberOfLines={2} style={styles.VideoTitle}>{video.snippet.title}</Text>
<Text style ={styles.Videostatistics}>{video.snippet.channelTitle+"ยท"+
nFormatter(video.statistics.viewCount,1)}</Text>
</View>
<TouchableOpacity>
<Icon name="more-vert" size={20} Color ="#3c3c3c"/>
</TouchableOpacity>
</View>
</TouchableOpacity>
</View>
);
}
}
function nFormatter(num, digits) {
var si = [
{ value: 1, symbol: "" },
{ value: 1E3, symbol: "k" },
{ value: 1E6, symbol: "M" },
{ value: 1E9, symbol: "G" },
{ value: 1E12, symbol: "T" },
{ value: 1E15, symbol: "P" },
{ value: 1E18, symbol: "E" }
];
var rx = /\.0+$|(\.[0-9]*[1-9])0+$/;
var i;
for (i = si.length - 1; i > 0; i--) {
if (num >= si[i].value) {
break;
}
}
return (num / si[i].value).toFixed(digits).replace(rx, "$1") + si[i].symbol;
}
const goToAbout = () => {
Actions.about()
}
const styles = StyleSheet.create({
container: {
padding: 15
},
Description:{
flexDirection:'row',
paddingTop:15
},
VideoDetails:{
paddingHorizontal:15,
flex:1
},
Videostatistics:{
fontSize:15,paddingTop:3
},
VideoTitle:{
fontSize:16,
color:'#3c3c3c'
}
});
You can get it with renderItem
renderItem={({item,index}) => <VideoItem video={item} index={index} />}
and on VideoItem.js you can fetch it using this.props.index
You can read more about renderItem here

Categories

Resources