React Native app only works after saving file twice - react-native

Basically, a request is made to an API and then the expected result is only presented on the screen after saving the file in vscode twice.
The API is returning the correct result the first time, the problem seems to be linked to useEffect and the updating of the components on the screen, because when I update the desirable result is presented.
I'm saving API data in AsyncStorage and then recovering. I have no idea if I'm doing it right or if there's a better way, but the point is that the app doesn't update the components the first time.
user.js (context)
import React, { createContext, useEffect, useState, useContext } from "react"
import AsyncStorage from "#react-native-async-storage/async-storage"
import ApiRequest from '../services/Api';
const UserContext = createContext({})
export const UserProvider = ({ children }) => {
const [user, setUser] = useState({})
const [services, setServices] = useState([])
useEffect(() => {
let isSubscribed = true;
const getStorage = async (isSubscribed) => {
const storagedToken = await AsyncStorage.getItem('token');
const storagedId = await AsyncStorage.getItem('id');
if(storagedToken && storagedId) {
isSubscribed ? getUser(storagedToken, storagedId) : null;
}
}
getStorage(isSubscribed);
return () => (isSubscribed = false);
}, [])
async function getUser(storagedToken, storagedId) {
try {
const resp = await ApiRequest.getUser(storagedToken, storagedId)
let user = JSON.stringify(resp.Cadastro)
await AsyncStorage.setItem('user', user);
} catch (error) {
console.log('Não foi possível recuperar os dados do usuário, tente novamente.')
}
}
return (
<UserContext.Provider value={{ user, currentService, services, setServiceDate, setServiceType, setCurrentService }}>
{children}
</UserContext.Provider>
)
}
export const useUser = () => {
return useContext(UserContext)
}
Api.js
import axios from 'axios';
import UrlGenerator from './UrlGenerator';
const ApiRequest = {
async getUser(token, id){
try {
const uri = await UrlGenerator.user();
const resp = await axios.post(uri, {
Token: token,
cadastroKey: id
});
return resp.data;
} catch (error) {
//setState(error.toString());
console.log(error);
}
}
}
export default ApiRequest;
WelcomeChamado.js
import React, { useEffect, useState } from 'react'
import { View, Image, ScrollView, StyleSheet, TouchableOpacity } from 'react-native'
import { LinearGradient } from 'expo-linear-gradient';
import { initialWindowMetrics, SafeAreaProvider, useSafeAreaInsets } from 'react-native-safe-area-context';
import NavBar from '../../../components/NavBar';
import { TextMuseo300, TextMuseo500 } from '../../../components/fonts/TextFonts';
import { theme } from '../../../global/theme';
import { TextInputMuseo300 } from '../../../components/fonts/TextInputFonts';
import AsyncStorage from '#react-native-async-storage/async-storage';
const { principalOne, principalTwo, principalThree, destaque, branco } = theme.colors;
import { Entypo } from '#expo/vector-icons';
import loadStoragedUser from '../../../helpers/getUser';
export function WelcomeChamado({ navigation }) {
const insets = useSafeAreaInsets();
const [user, setUser] = useState({});
const [foto, setFoto] = useState('');
useEffect(() => {
async function getUser() {
setUser(await loadStoragedUser());
}
const getInfo = async () => {
const storagedFoto = await AsyncStorage.getItem('#lica:foto');
setFoto(storagedFoto);
}
getInfo();
getUser();
}, []);
const nextScreen = () => {
navigation.navigate("AguardarChamado");
}
return (
<ScrollView
showsVerticalScrollIndicator={false}
contentContainerStyle={{
flexGrow: 1,
}}>
<SafeAreaProvider initialMetrics={initialWindowMetrics}
style={
styles.container,
{
paddingTop: insets.top,
paddingLeft: insets.left,
paddingBottom: insets.bottom,
paddingRight: insets.right,
}
}>
<LinearGradient
start={{ x: 0, y: 0.5 }}
end={{ x: 1, y: 0.5 }}
locations={[0, 0.2, 0.4, 0.6, 0.8, 1]}
colors={['#8EF4F0', '#D6FDFA', '#F8FEFE', '#F8FEFE', '#D6FDFA', '#8EF4F0']}
style={{
flex: 1
}}>
<NavBar navigation={navigation} />
<View style={{
alignItems: 'center',
marginTop: '5%'
}}>
<TextMuseo300 style={{
color: '#2E8F71',
marginTop: '1%',
fontWeight: 'bold',
marginBottom: 10
}}>Olá</TextMuseo300>
<View style={{
justifyContent: 'center',
alignItems: 'center',
}}>
<Image
source={{ uri: `data:image/gif;base64,${foto}` }}
style={{
width: 100,
height: 100,
borderRadius: 50,
borderWidth: 1,
borderColor: destaque,
}}
resizeMode="cover"
/>
<View style={{
position: 'absolute',
top: -5,
right: 0,
backgroundColor: '#2E8F71',
width: 32,
height: 32,
borderRadius: 16,
paddingLeft: 2,
alignItems: 'center',
justifyContent: 'center'
}}>
<Entypo
name="bell"
size={25}
color="#FFF"
/>
</View>
</View>
<TextMuseo300 style={{
color: '#2E8F71',
marginTop: '1%',
fontWeight: 'bold',
marginTop: 10
}}>{user?.CadastroNome}</TextMuseo300>
<TextMuseo300 style={{
color: '#2E8F71',
marginTop: '1%'
}}>{user?.CadastroUser}</TextMuseo300>
</View>
<View style={{
marginTop: 30,
alignItems: 'center',
}}>
<TextMuseo300 style={{
color: '#2E8F71',
marginTop: '2%',
maxWidth: 120,
fontSize: 20,
textAlign: 'center'
}}>Você está disponível para receber chamados?</TextMuseo300>
<TouchableOpacity onPress={nextScreen}>
<View style={{
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#2E8F71',
borderRadius: 10,
width: 120,
height: 30,
marginTop: 50
}}>
<TextMuseo300 style={{
color: '#FFF',
marginTop: '2%',
maxWidth: 120,
fontSize: 20,
fontWeight: 'bold',
textAlign: 'center'
}}>Sim, estou.</TextMuseo300>
</View>
</TouchableOpacity>
</View>
</LinearGradient>
</SafeAreaProvider>
</ScrollView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
center: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
});

Related

TypeError: undefined is not a function [React Native]

I need help with this, I'm stuck
This is my custom component DataSlideInput.js
and the debugger gives me TypeError: undefined is not a function in every call to any custom component. Like or
import React from 'react';
import {View, Text, TouchableOpacity, StyleSheet} from 'react-native';
import {Colors} from './colors.js';
import {TextInput} from 'react-native-paper';
import {CheckBox, Icon} from '#rneui/themed';
import {useNavigation} from '#react-navigation/core';
import Toast from 'react-native-simple-toast';
import {setUsername, setPassword, setRememberMe} from '../redux/loginSlice';
import {useSelector, useDispatch} from 'react-redux';
const DataSlideInput = props => {
const userName = useSelector(state => state.login.userName);
const password = useSelector(state => state.login.password);
const dispatch = useDispatch();
return (
<TextInput
theme={{roundness: 30}}
placeholder={props.placeholder}
placeholderTextColor={Colors.placeholderColor}
autoCapitalize="none"
mode="outlined"
label={props.label}
secureTextEntry={props.secureTextEntry ? true : false}
outlineColor={Colors.secondary}
activeOutlineColor={Colors.secondary}
style={styles.dataSlideInput}
value={props.label == 'Email' ? userName : password}
onChangeText={value => {
if (props.label == 'Email') {
dispatch(setUsername(value));
}
if (props.label == 'Password') {
dispatch(setPassword(value));
}
}}
/>
);
};
const RememberMe = () => {
const dispatch = useDispatch();
const rememberMe = useSelector(state => state.login.rememberMe);
return (
<View style={styles.rememberMe}>
<CheckBox
checkedIcon={
<Icon
name="radio-button-checked"
type="material"
color={Colors.secondary}
size={25}
iconStyle={{marginRight: 10}}
/>
}
uncheckedIcon={
<Icon
name="radio-button-unchecked"
type="material"
color={Colors.secondary}
size={25}
iconStyle={{marginRight: 10}}
/>
}
checked={rememberMe}
onPress={() => {
dispatch(setRememberMe(!rememberMe));
}}
/>
<Text style={styles.rememberMeText}>Recordarme en este dispositivo</Text>
</View>
);
};
const LogInButton = () => {
const userName = useSelector(state => state.login.userName);
const password = useSelector(state => state.login.password);
const navigation = useNavigation();
const handleSubmit = () => {
if (userName != '' && password != '') {
navigation.navigate('MapaOnline');
} else {
if (userName == '' && password == '')
Toast.show('Por favor, complete E-mail y Contraseña', Toast.SHORT);
else {
if (userName == '')
Toast.show(
'El casillero de E-mail no puede quedar vacio',
Toast.SHORT,
);
if (password == '')
Toast.show('La contraseña no puede ser vacia', Toast.SHORT);
}
}
};
return (
<TouchableOpacity
style={styles.dataSlideLogInButton}
onPress={() => handleSubmit()}>
<Text style={styles.dataSlideLogInButtonText}>Entrar</Text>
</TouchableOpacity>
);
};
const ConfigButton = () => {
const navigation = useNavigation();
return (
<TouchableOpacity
onPress={() => navigation.navigate('Config')}
style={styles.dataSlideConfig}>
<Text style={styles.dataSlideConfigText}>Ir a configuración</Text>
</TouchableOpacity>
);
};
const styles = StyleSheet.create({
dataSlideInput: {
borderRadius: 35,
backgroundColor: Colors.primary,
width: '80%',
alignSelf: 'center',
margin: 10,
height: 45,
},
rememberMe: {
flexDirection: 'row',
width: '80%',
alignSelf: 'center',
height: 60,
},
rememberMeText: {
fontSize: 17,
alignSelf: 'center',
marginLeft: -20,
marginBottom: 7,
fontFamily: 'sans-serif-condensed',
},
dataSlideLogInButton: {
borderWidth: 1,
borderColor: Colors.secondary,
backgroundColor: Colors.secondary,
alignItems: 'center',
alignSelf: 'center',
justifyContent: 'center',
width: '80%',
height: 50,
borderRadius: 35,
},
dataSlideLogInButtonText: {
fontSize: 17,
fontWeight: 'bold',
color: Colors.primary,
},
dataSlideConfig: {
marginTop: 10,
alignSelf: 'center',
},
dataSlideConfigText: {
fontFamily: 'sans-serif-condensed',
alignSelf: 'center',
fontSize: 17,
color: Colors.headerColor,
},
});
export {DataSlideInput, RememberMe, LogInButton, ConfigButton};
And I'm trying to put it here. This was working before, but this morning stop...
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* Generated with the TypeScript template
* https://github.com/react-native-community/react-native-template-typescript
*
* #format
*/
import 'react-native-gesture-handler';
import React, {useEffect} from 'react';
import {
SafeAreaView,
StyleSheet,
Text,
Image,
View,
ImageBackground,
} from 'react-native';
import * as Animatable from 'react-native-animatable';
import {Colors} from '../component/colors';
import {useDispatch} from 'react-redux';
import {createTable, getDataFromDB} from '../Database/databaseConfig';
import {
DataSlideInput,
RememberMe,
LogInButton,
ConfigButton,
} from '../component/DataSlideInput';
//configuration -> loading
// related items -> elements or files
const currentRow = ''; //activities detailedInformation relatedItems editedElements connectedElements
const Login = () => {
const dispatch = useDispatch();
useEffect(() => {
createTable();
getDataFromDB(dispatch);
}, []);
return (
<SafeAreaView style={styles.backgroundStyle}>
<ImageBackground
source={require('../component/icons/background.jpg')}
resizeMode="cover"
style={{flex: 1}}>
<Text style={styles.headerText}>ISMobile</Text>
<Image
style={styles.companyLogo}
source={require('../component/icons/logo.png')}
/>
<View style={{flex: 1, justifyContent: 'flex-end'}}>
<Animatable.View animation="fadeInUp" style={styles.dataSlide}>
<Text style={styles.dataSlideHeader}>
Ingresá tus datos para continuar.
</Text>
<DataSlideInput
placeholder="Email"
label="Email"
secureTextEntry={false}
/>
<DataSlideInput
placeholder="Password"
label="Password"
secureTextEntry={true}
/>
<RememberMe />
{/* Clicking LogIn button redirects to mapaOnline */}
<LogInButton />
{/* Clicking Config button redirects to config */}
<ConfigButton />
</Animatable.View>
</View>
</ImageBackground>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
headerText: {
color: Colors.primary,
textAlign: 'center',
fontSize: 20,
marginTop: 25,
fontWeight: 'bold',
},
backgroundStyle: {
flex: 1,
height: '100%',
backgroundColor: Colors.secondary,
justifyContent: 'space-between',
},
companyLogo: {
marginTop: 60,
alignSelf: 'center',
width: 100,
height: 100,
},
dataSlide: {
borderTopLeftRadius: 30,
borderTopRightRadius: 30,
paddingHorizontal: 20,
paddingVertical: 30,
width: '100%',
height: '70%',
backgroundColor: Colors.primary,
},
dataSlideHeader: {
fontFamily: 'sans-serif-condensed',
alignSelf: 'center',
fontSize: 20,
marginBottom: 15,
},
dataSlideConfig: {
marginTop: 10,
alignSelf: 'center',
},
dataSlideConfigText: {
fontFamily: 'sans-serif-condensed',
alignSelf: 'center',
fontSize: 17,
color: Colors.headerColor,
},
});
export default Login;
{
/* <TouchableOpacity
onPress={() => navigation.navigate(currentRow)}
style={{
marginTop: 10,
alignSelf: "center",
}}>
<Text style={{
fontFamily: "sans-serif-condensed",
alignSelf: 'center',
fontSize: 17,
color: Colors.headerColor
}}>debug</Text>
</TouchableOpacity> */
}
Terminal Error
If anyone knows how to fix it, I would be very grateful.
The problem was the version of react-redux.
I installed a previous version and it solved the problem
npm install react-redux#7.0.2

I want to add Async Storage to my flatlist in todo list app

I want to add Async Storage to my flatlist in todo list app.
this is my App.js code:
import { StatusBar } from 'expo-status-bar';
import {
StyleSheet,
Text,
View,
KeyboardAvoidingView,
FlatList,
TextInput,
TouchableOpacity,
Keyboard,
} from 'react-native';
import React, { useState, useEffect } from 'react';
import {
Poppins_100Thin,
Poppins_100Thin_Italic,
Poppins_200ExtraLight,
Poppins_200ExtraLight_Italic,
Poppins_300Light,
Poppins_300Light_Italic,
Poppins_400Regular,
Poppins_400Regular_Italic,
Poppins_500Medium,
Poppins_500Medium_Italic,
Poppins_600SemiBold,
Poppins_600SemiBold_Italic,
Poppins_700Bold,
Poppins_700Bold_Italic,
Poppins_800ExtraBold,
Poppins_800ExtraBold_Italic,
Poppins_900Black,
Poppins_900Black_Italic,
} from '#expo-google-fonts/poppins';
import { useFonts } from 'expo-font';
import Task from './components/Task';
import AppLoading from 'expo-app-loading';
export default function App() {
const [task, setTask] = useState();
const [taskItems, setTaskItems] = useState([]);
let [fontsLoaded, error] = useFonts({
Poppins_100Thin,
Poppins_100Thin_Italic,
Poppins_200ExtraLight,
Poppins_200ExtraLight_Italic,
Poppins_300Light,
Poppins_300Light_Italic,
Poppins_400Regular,
Poppins_400Regular_Italic,
Poppins_500Medium,
Poppins_500Medium_Italic,
Poppins_600SemiBold,
Poppins_600SemiBold_Italic,
Poppins_700Bold,
Poppins_700Bold_Italic,
Poppins_800ExtraBold,
Poppins_800ExtraBold_Italic,
Poppins_900Black,
Poppins_900Black_Italic,
});
if (!fontsLoaded) {
return <AppLoading />;
}
const handleAddTask = async () => {
try {
Keyboard.dismiss();
setTaskItems([...taskItems, task]);
setTask('');
} catch (err) {
console.log(err);
}
};
const completeTask = (index) => {
let itemsCopy = [...taskItems];
itemsCopy.splice(index, 1);
setTaskItems(itemsCopy);
};
const deleteItem = (index) => {
let arr = [...taskItems];
arr.splice(index, 1);
setTaskItems(arr);
};
return (
<View style={styles.container}>
{/* Todays Tasks */}
<View style={styles.taskWrapper}>
<Text style={styles.sectionTitle}>Today's Tasks</Text>
<View style={styles.items}>
{/* This is where the tasks will go! */}
<FlatList
data={taskItems}
keyExtractor={(item) => item.id}
renderItem={({ item, index }) => (
<Task text={item} handleDelete={() => deleteItem(index)} />
)}
/>
</View>
</View>
{/* Write a Task */}
<KeyboardAvoidingView style={styles.writeTaskWrapper}>
<TextInput
style={styles.input}
placeholder={'Write A Task'}
value={task}
onChangeText={(text) => setTask(text)}
/>
<TouchableOpacity onPress={() => handleAddTask()}>
<View style={styles.addWrapper}>
<Text style={styles.addText}>+</Text>
</View>
</TouchableOpacity>
</KeyboardAvoidingView>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#E8EAED',
},
taskWrapper: {
paddingTop: 80,
paddingHorizontal: 20,
},
sectionTitle: {
fontSize: 24,
backgroundColor: '#fff',
fontFamily: 'Poppins_600SemiBold',
borderRadius: 10,
margin: 'auto',
width: 250,
height: 60,
textAlign: 'center',
shadowColor: '#000',
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.2,
shadowRadius: 2,
elevation: 5,
paddingTop: 10,
},
items: {
marginTop: 30,
},
writeTaskWrapper: {
position: 'absolute',
bottom: 60,
width: '100%',
flexDirection: 'row',
justifyContent: 'space-around',
alignItems: 'center',
},
input: {
paddingVertical: 15,
paddingHorizontal: 15,
backgroundColor: '#fff',
borderRadius: 60,
width: 250,
fontFamily: 'Poppins_400Regular',
shadowColor: '#000',
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.5,
shadowRadius: 2,
elevation: 3,
},
addWrapper: {
width: 60,
height: 60,
backgroundColor: '#fff',
borderRadius: 60,
justifyContent: 'center',
alignItems: 'center',
shadowColor: '#000',
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.5,
shadowRadius: 2,
elevation: 3,
},
addText: {},
});
THIS IS MY TASK.JS CODE:
import React from 'react';
import {View,Text,StyleSheet,Dimensions,Animated,TouchableOpacity} from 'react-native';
import AppLoading from 'expo-app-loading'
import {
Poppins_100Thin,
Poppins_100Thin_Italic,
Poppins_200ExtraLight,
Poppins_200ExtraLight_Italic,
Poppins_300Light,
Poppins_300Light_Italic,
Poppins_400Regular,
Poppins_400Regular_Italic,
Poppins_500Medium,
Poppins_500Medium_Italic,
Poppins_600SemiBold,
Poppins_600SemiBold_Italic,
Poppins_700Bold,
Poppins_700Bold_Italic,
Poppins_800ExtraBold,
Poppins_800ExtraBold_Italic,
Poppins_900Black,
Poppins_900Black_Italic
} from '#expo-google-fonts/poppins'
import {useFonts} from 'expo-font'
import Swipeable from 'react-native-gesture-handler/Swipeable';
const SCREEN_WIDTH = Dimensions.get('window').width;
const Task = (props) => {
let [fontsLoaded,error]=useFonts({
Poppins_100Thin,
Poppins_100Thin_Italic,
Poppins_200ExtraLight,
Poppins_200ExtraLight_Italic,
Poppins_300Light,
Poppins_300Light_Italic,
Poppins_400Regular,
Poppins_400Regular_Italic,
Poppins_500Medium,
Poppins_500Medium_Italic,
Poppins_600SemiBold,
Poppins_600SemiBold_Italic,
Poppins_700Bold,
Poppins_700Bold_Italic,
Poppins_800ExtraBold,
Poppins_800ExtraBold_Italic,
Poppins_900Black,
Poppins_900Black_Italic
})
if (!fontsLoaded){
return <AppLoading/>
}
const leftSwipe = (progress, dragX) => {
const scale = dragX.interpolate({
inputRange: [0, 100],
outputRange: [0, 1],
extrapolate: 'clamp',
});
return (
<TouchableOpacity onPress={props.handleDelete} activeOpacity={0.6}>
<View style={styles.deleteBox}>
<Animated.Text style={{transform: [{scale: scale}],color:'#fff',fontFamily:"Poppins_400Regular",fontSize:18}}>
Delete
</Animated.Text>
</View>
</TouchableOpacity>
);
};
return(
<Swipeable renderLeftActions={leftSwipe}>
<View style={styles.item}>
<View style={styles.itemLeft}>
<View style={styles.square}>
</View>
<Text style={styles.itemText}>
{props.text}
</Text>
</View>
<View style={styles.circular}>
</View>
</View>
</Swipeable>
)
}
const styles = StyleSheet.create({
item:{
backgroundColor:'white',
padding:15,
borderRadius:10,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
marginBottom:20,
shadowColor: '#000',
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.5,
shadowRadius: 2,
elevation: 3
},
itemLeft:{
flexDirection: 'row',
alignItems: 'center',
flexWrap:'wrap',
},
square:{
width:24,
height:24,
backgroundColor:'#55BCF6',
opacity:0.5,
borderRadius:5,
marginRight:15,
},
itemText:{
maxWidth:'80%',
fontFamily:'Poppins_400Regular'
},
circular:{
width:12,
height:12,
borderColor:'#55BCF6',
borderWidth:2,
borderRadius:5
},
deleteBox:{
backgroundColor:'red',
justifyContent:'center',
alignItems:'center',
width:100,
height:55,
borderRadius:10,
shadowColor: '#000',
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.5,
shadowRadius: 2,
elevation: 5,
}
});
export default Task;
i am learning react native so i dont know much about it
so i want to add async storage such that its shows the tasks which are created after re-opening the app
kindly help with providing code
and yeah i have used expo and swipeable for deleting the tasks
import async-storage
import AsyncStorage from '#react-native-async-storage/async-storage';
get stored task
const task await AsyncStorage.getItem('task')
if(task!=null)
switch(task{
... your cases ...
set a task
await AsyncStorage.setItem('task', 'taskName')
in case refreshing task
await AsyncStorage.removeItem('keyName')

how to validate DateTimePickerModal with yup and formik in React native?

Here is my screen component with two textinputs from the link. I have removed some other code that isn't necessary to this issue.
When i choose the date from the popup it appears in the text input but doesnt get validated.
I cannot use the result of DatePicker component as it is , so i am doing some formating and saved to a function getDate.
How would you go about implemnting this ? is there any better way
enter image description here
import React, { useState, useContext, useEffect } from 'react';
import {
StyleSheet,
View,
Text,
TextInput,
TouchableOpacity,
ScrollView,
KeyboardAvoidingView,
Platform,
Image,
} from 'react-native';
import { icons, COLORS, } from '../constants';
import { Formik } from 'formik';
import * as yup from "yup";
import client from '../api/client';
import DateTimePickerModal from "react-native-modal-datetime-picker";
const addfarm = ({ navigation, Arrival_Date }) => {
const addFarmValidationSchema = yup.object().shape({
Farm_Code: yup.string().required('Please Enter the chick price'),
Arrival_Date: yup.string().required('Please Choose a date'),
});
const [isDatePickerVisible, setDatePickerVisibility] = useState(false);
const [date, setDate] = useState('');
const showDatePicker = () => {
setDatePickerVisibility(true);
};
const hideDatePicker = () => {
setDatePickerVisibility(false);
};
const handleConfirm = (date) => {
hideDatePicker();
setDate(date);
};
const getDate = () => {
let tempDate = JSON.stringify(date).split(/[ ",T,]/);
return date !== ''
? `${tempDate[1]}`
: '';
};
const newDate = getDate();
const addFarmInfo = {
Farm_Code: '',
Arrival_Date: '',
};
const add = async (values) => {
const res = await client({
method: 'POST',
url: '/Farm/SaveFarm',
data: JSON.stringify({ ...values, id })
})
.then(res => console.log(res.data))
.catch(err => console.log(err))
}
return (
<KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : null}
style={{ flex: 1 }}>
<ScrollView style={styles.container}>
<Formik
initialValues={addFarmInfo}
validateOnMount={true}
onSubmit={add}
validationSchema={addFarmValidationSchema}>
{({
handleChange,
handleBlur,
handleSubmit,
values,
touched,
errors,
isValid,
setFieldValue,
}) => {
const {
Farm_Code,
Arrival_Date,
} = values
return (
<View
style={{
paddingHorizontal: '10%',
paddingTop: 50,
marginTop: 50,
backgroundColor: COLORS.main_background,
}}>
<Text style={styles.auth_text}>Add Farm</Text>
<Text style={styles.tag}>
Farm Code:
</Text>
<View
style={[styles.textInputView, { marginBottom: 10 }]}>
<TextInput
onChangeText={handleChange('Farm_Code')}
onBlur={handleBlur('Farm_Code')}
value={Farm_Code}
placeholder="Farm Code"
placeholderTextColor={COLORS.placeholder_fonts}
selectionColor={COLORS.drawer_button}
style={styles.textInput}
/>
<Image
source={!errors.Farm_Code ? icons.tick : icons.close}
resizeMode="stretch"
style={{
width: 18,
height: 18,
tintColor: !errors.Farm_Code ? COLORS.drawer_button : 'red',
alignItems: 'center',
marginRight: 10,
}}
/>
</View>
{(errors.Farm_Code && touched.Farm_Code) &&
<Text style={styles.errors}>{errors.Farm_Code}</Text>
}
<Text style={styles.tag}>
Arrival Date:
</Text>
<View
style={[styles.textInputView, { marginBottom: 10 }]}>
<TextInput
onChangeText={handleChange('Arrival_Date')}
onBlur={handleBlur('Arrival_Date')}
value={newDate}
onFocus={showDatePicker}
placeholder="yyyy/mm/dd"
placeholderTextColor={COLORS.placeholder_fonts}
selectionColor={COLORS.drawer_button}
style={styles.textInput}
/>
<TouchableOpacity style={{ marginRight: 10, }}
onPress={showDatePicker}
>
<DateTimePickerModal
isVisible={isDatePickerVisible}
mode="date"
onConfirm={handleConfirm}
onCancel={hideDatePicker}
/>
<Image
source={icons.calendar}
resizeMode="stretch"
style={{
width: 18,
height: 18,
tintColor: COLORS.secondary_fonts,
alignItems: 'center'
}}
/>
</TouchableOpacity>
<Image
source={!errors.Arrival_Date ? icons.tick : icons.close}
resizeMode="stretch"
style={{
width: 18,
height: 18,
tintColor: !errors.Arrival_Date ? COLORS.drawer_button : 'red',
alignItems: 'center',
marginRight: 10,
}}
/>
</View>
{(errors.Arrival_Date && touched.Arrival_Date) &&
<Text style={styles.errors}>{errors.Arrival_Date}</Text>
}
{(errors.Arrival_Date && touched.Arrival_Date) &&
<Text style={styles.errors}>{errors.Arrival_Date}</Text>
}
{/* Save */}
<TouchableOpacity
disabled={!isValid}
onPress={handleSubmit}
style={[styles.button, { backgroundColor: isValid ? COLORS.authButtons : COLORS.placeholder_fonts, marginTop: 10 }]}>
<Text style={styles.button_Text}>Save</Text>
</TouchableOpacity>
</View>
)
}
}
</Formik >
</ScrollView>
</KeyboardAvoidingView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: COLORS.main_background,
},
textInput: {
flex: 1,
paddingLeft: 10,
color: 'black',
},
auth_text: {
fontSize: 20,
fontWeight: 'bold',
textAlign: 'center',
marginBottom: 5,
},
button: {
height: 50,
width: '100%',
marginVertical: 20,
borderRadius: 10,
alignItems: 'center',
justifyContent: 'center',
},
button_Text: {
fontSize: 18,
color: COLORS.white,
},
login_nav: {
fontSize: 12,
textAlign: 'center',
fontWeight: '400',
marginTop: 10,
},
errors: {
fontSize: 14,
color: 'red',
fontWeight: '400',
marginTop: 5,
},
textInputView: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
borderWidth: 1,
borderRadius: 10,
height: 50,
width: '100%',
borderColor: COLORS.secondary_fonts,
},
tag: {
color: 'black',
fontSize: 15,
marginBottom: 4,
marginLeft: 4
},
});
export default addfarm;
If you want formik to handle the validation, you should call the setFieldValue method and it will trigger the validation as the documentation says

Navigating among three screens

I am about to making an app with React Native and I have three screens with deferent styles (themes). I want to navigate among these three screens, So I am passing data from my main screen (App.js) as parent to the other three as child (screen1, screen2, screen3). I used a modal which has three button in it and i want whenever I pressed one of them, the screen change to the pressed one. This is my App.js file
import React, { useState, useEffect } from "react";
import { StyleSheet, View } from "react-native";
import Screen1 from "./screens/CalcScreen";
import Screen2 from "./screens/Screen1";
import Screen3 from "./screens/Screen2";
export default function App() {
const [whiteScreen, setWhiteScreen] = useState(false);
const [darkScreen, setDarkScreen] = useState(false);
const [pinkScreen, setPinkScreen] = useState(false);
const whiteScreenHandler = () => {
setWhiteScreen(true);
setDarkScreen(false);
setPinkScreen(false);
};
const darkScreenHandler = () => {
setDarkScreen(true);
setWhiteScreen(false);
setPinkScreen(false);
};
const pinkScreenHander = () => {
setPinkScreen(true);
setWhiteScreen(false);
setDarkScreen(false);
};
let content = <screen1 setDarkScreen={darkScreenHandler} />;
let content2 = <Screen2 setWhiteScreen={whiteScreenHandler} />;
let content3 = <Screen3 setPinkScreen={pinkScreenHander} />;
if (darkScreen) {
content = content;
} else if (whiteScreen) {
content = content2;
} else if (pinkScreen) {
content = content3;
}
return <View style={styles.container}>{content}</View>;
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#374351",
},
});
And this is one of my screens and my modals in my screens, the other two screens are same in coding but not in styles and I used this modal in each three screens,(does it right to use in three screens?) anyway whenever I'm pressing modal's button to change the screens i got props.screen handler() is not a function. What is wrong in my code?
import React, { useState } from "react";
import {
StyleSheet,
Text,
ScrollView,
View,
TouchableOpacity,
Alert,
Animated,
Modal,
Pressable,
} from "react-native";
const Screen1 = (props) => {
return (
<View style={styles.screen}>
<Modal
animationType="slide"
transparent={true}
visible={modalVisible}
onRequestClose={() => {
setModalVisible(!modalVisible);
}}
>
<View style={styles.centeredView}>
<View style={styles.modalView}>
<View style={styles.button}></View>
<Text style={styles.modalText}>Themes</Text>
<TouchableOpacity
style={styles.darkTheme}
onPress={() => {
props.setDarkScreen();
}}
>
<Text>Dark</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.whiteTheme}
onPress={() => {
props.setWhiteScreen();
}}
>
<Text>White</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.pinkTheme}
onPress={() => {
props.setPinkScreen();
}}
>
<Text>Pink</Text>
</TouchableOpacity>
<Pressable
style={[styles.buttonClose]}
onPress={() => setModalVisible(!modalVisible)}
>
<Text style={styles.textStyle}>X</Text>
</Pressable>
</View>
</View>
</Modal>
<Pressable
style={[styles.button, styles.buttonOpen]}
onPress={() => setModalVisible(true)}
>
<Text style={styles.openText}>{">"}</Text>
</Pressable>
</View>
)
}
const styles = StyleSheet.create({
screen: {
backgroundColor: "#fafcff",
},
centeredView: {
// flex: 1,
marginStart: 15,
justifyContent: "center",
alignItems: "center",
// marginTop: 70,
},
modalView: {
marginTop: 200,
backgroundColor: "rgba(255,255,255,0.5)",
borderRadius: 20,
padding: 20,
alignItems: "center",
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.5,
shadowRadius: 4,
elevation: 5,
},
button: {
borderRadius: 15,
padding: 10,
elevation: 2,
justifyContent: "center",
alignItems: "center",
marginTop: 20,
},
buttonOpen: {
backgroundColor: "rgba(1,143,132,0.6)",
position: "absolute",
marginTop: 45,
marginStart: -25,
elevation: 2,
height: 70,
width: 40,
},
buttonClose: {
backgroundColor: "rgba(1,1,1,1)",
height: 40,
width: 40,
borderRadius: 50,
// padding: 10,
elevation: 2,
justifyContent: "center",
alignItems: "center",
marginTop: 20,
},
textStyle: {
color: "white",
// fontWeight: "bold",
textAlign: "center",
},
modalText: {
marginBottom: 10,
textAlign: "center",
},
openText: {
fontSize: 25,
fontWeight: "bold",
color: "white",
textAlign: "right",
},
});
export default Screen1;
You can easily doing that by using "React Native Navigation". Here is the documentation:
https://reactnavigation.org/docs/getting-started. I also recommend you that you might want to create your screens into different files to make your code cleaner.

im trying to add on press highlight the selected item in the flatlist using the keyExtractor

import React, {useState} from 'react';
import {Image, FlatList, Dimensions, StyleSheet} from 'react-native';
import FastImage from 'react-native-fast-image'
const picsumImages = new Array(28).fill("http://placeimg.com/640/360/any");
let generateRandomNum = () => Math.floor(Math.random() * 1001);
function renderItem({ item }) {
return (
<FastImage
source={{ uri: item}}
style={styles.itemView}
/>
);
}
const OtasView = (props) => {
const [images, setImages] = useState(picsumImages);
return (
<FlatList data={images} renderItem={renderItem} numColumns={3} style={{ marginLeft: 18, marginRight: 18, marginTop: 40 }} keyboardShouldPersistTaps="always"
showsVerticalScrollIndicator={false} keyExtractor={(renderItem) => generateRandomNum().toString()}/>
);
};
const styles = StyleSheet.create({
screen: {
flex: 1,
padding: 10,
alignItems: "center",
},
itemView: {
flex: 1 / 3,
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
margin: 5,
aspectRatio: 1,
borderRadius: 200 / 2
},
});
export default OtasView;
This might help
const [images, setImages] = useState(picsumImages);
onSelect = index => {
const data = […images].map(item => item.selected = false);
data[index].selected = true;
setImages(data);
}
function renderItem({ item, index }) {
const style = index.selected ? styles.profileImgContainer : {};
return (
<TouchableHighlight style={style} onPress={() => onSelect(index)}>
<FastImage
source={{ uri: item}}
style={styles.itemView}
/>
</TouchableHighlight>
);
export default styles = StyleSheet.create({
profileImgContainer: {
marginLeft: 8,
height: 80,
width: 80,
borderRadius: 40,
},
itemView: {
flex: 1 / 3,
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
margin: 5,
aspectRatio: 1,
borderRadius: 200 / 2
}
});