I am new with react native and when i try do this
<TextInput
style={styles.input}
onChange={(text) => setPontoValue(text)}
/>
i receive this error
TS2345: Argument of type 'NativeSyntheticEvent<TextInputChangeEventData>' is not assignable to parameter of type 'SetStateAction<undefined>'. Type 'NativeSyntheticEvent<TextInputChangeEventData>' provides no match for the signature '(prevState: undefined): undefined'.
all code is below
import React, { useState } from 'react'
import {
TextInput,
TouchableOpacity,
StyleSheet,
SafeAreaView,
Text,
View, Button,
} from 'react-native'
export default function App() {
const [pontoValue, setPontoValue] = useState()
const [dataValue, setDataValue] = useState()
return (
<SafeAreaView style={styles.container}>
<View style={styles.repositoryContainer}>
<TextInput
style={styles.input}
onChange={(text) => setPontoValue(text)}
/>
<TextInput
style={styles.input}
value={dataValue}
/>
<TouchableOpacity>
<Button
title="Calcular"
onPress={teste}>Converter
</Button>
</TouchableOpacity>
</View>
</SafeAreaView>
)
function teste() {
if (pontoValue) {
setDataValue(pontoValue.replace(/[ .]+/g, ''))
}
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignContent: 'center',
backgroundColor: '#7199c1',
},
repositoryContainer: {
marginBottom: 15,
marginHorizontal: 15,
backgroundColor: '#fff',
padding: 20,
},
input: {
height: 40,
padding: 5,
borderColor: 'gray',
borderWidth: 1,
},
buttonText: {
marginVertical: 11,
fontSize: 14,
fontWeight: 'bold',
color: '#fff',
backgroundColor: '#7159c1',
padding: 15,
},
})
onChange event returns an event object which has nativeEvent function which providers access to the following properties: { eventCount, target, text}
you need the text property, so you can use:
onChange={(event) => setPontoValue(event.nativeEvent.text)}
or
onChangeText={(text) => setPontoValue(text)}
I suggest you to use onChangeText prop.
onChangeText is a prop that gives you only text changes.
onChange on the other hand, passes an event.
So, try this
<TextInput
style={styles.input}
onChangeText={(text) => setPontoValue(text)}
/>
Also, always initialize your state variables.
const [pontoValue, setPontoValue] = useState('')
const [dataValue, setDataValue] = useState('')
It will reduce to chance of getting undefined errors.
Hope it works.
Related
I'm trying to make an app similar to a chatting service in react-native.
I have 3 files: fpLogin(Login page), ChatsScreen(The screen where you can see all of your active chats), ChatsComponent(I'm passing chats in chatsScreen as chatsComponent as it seems more efficient to me)
It's still a work in progress but I keep getting stuck on this one error which says: "Cannot read properties of undefined (reading 'width')
Would be much appreciated if someone could help me out here as I am stuck on this for about 3 days now...
fpLogin
import React, { useState } from "react";
import {
Text,
View,
Button,
StyleSheet,
TextInput,
ImageBackground,
} from "react-native";
const fpLogin = ({ navigation }) => {
const [username, setUsername] = useState("");
const [password, setPasword] = useState("");
const flag = false;
return (
<ImageBackground
style={styles.background}
source={require("../../assets/background.jpg")}
>
<View>
<Text style={styles.mid}>Login page</Text>
<TextInput
style={styles.textBox}
placeholder={"Enter Username"}
autoCapitalize="none"
autoCorrect={false}
value={username}
onChangeText={(newValue) => setUsername(newValue)}
/>
<TextInput
style={styles.textBox}
placeholder={"Enter Password"}
autoCapitalize="none"
autoCorrect={false}
secureTextEntry={true}
value={password}
onChangeText={(newValue) => setPasword(newValue)}
/>
<Button title="Login" onPress={() => navigation.navigate("Chat")} />
</View>
</ImageBackground>
);
};
styles = StyleSheet.create({
mid: {
fontSize: 50,
textAlign: "center",
},
textBox: {
fontSize: 30,
textAlign: "center",
borderWidth: 3,
borderColor: "black",
margin: 20,
},
background: {
flex: 1,
width: null,
},
});
export default fpLogin;
ChatsScreen
import React from "react";
import { View, Text, Button, StyleSheet, ImageBackground } from "react-native";
import ChatsComponent from "../components/ChatsComponent";
const ChatsScreen = () => {
return (
<View>
<ImageBackground
source={require("../../assets/background.jpg")}
style={styles.background}
/>
<ChatsComponent name="Jannet" />
<ChatsComponent name="Mike" />
<ChatsComponent name="Adam" />
<ChatsComponent name="Ofek" />
<ChatsComponent name="Matti" />
<ChatsComponent name="Yaniv" />
<ChatsComponent name="Shani" />
<ChatsComponent name="Noy" />
<ChatsComponent name="Paul" />
<ChatsComponent name="Daniel" />
</View>
);
};
styles = StyleSheet.create({
background: {
flex: 1,
},
});
export default ChatsScreen;
ChatsComponent
import React from "react";
import { View, Text, Button, StyleSheet, TouchableOpacity } from "react-native";
const Chats = ({ name }) => {
return (
<View>
<TouchableOpacity style={styles.buttonFacebookStyle}>
<Text style={styles.nameStyle}>{name}</Text>
</TouchableOpacity>
</View>
);
};
styles = StyleSheet.create({
buttonFacebookStyle: {
flexDirection: "row",
alignItems: "center",
backgroundColor: "#485a96",
borderWidth: 0.5,
borderColor: "#fff",
height: 40,
width: null,
borderRadius: 4,
margin: 5,
},
nameStyle: {
alignContent: "center",
},
});
export default Chats;
This is the ERROR screen I am getting on my npm
https://i.stack.imgur.com/INV6P.jpg
Thanks in advance to anyone who is willing to help :)
I think you need to explicitely set the size of ImageBackground try:
<ImageBackground
style={styles.background}
source={require("../../assets/background.jpg")}
>
...
...
background: {
flex: 1,
width: '100%',
height: '100%',
resizeMode: 'cover'}
You are not declaring styles as constant.
Try to use it like this:
const styles = StyleSheet.create({
`enter your style here`
})
Also, you can use width directly without calling on style prop. ImageBackground has width and height API.
<ImageBackground
width={'100%'}
height={'100%'}>
`you can use width and height`
</ImageBackground>
so I am trying to perform some onChange event, as I learned, but somehow it throws me the error that the onChange function is undefined. The right dependency is installed (react-hook-form).
Here is my code.
Someone a idea, where the issue is coming from?
https://codesandbox.io/embed/jolly-butterfly-diqb1?fontsize=14&hidenavigation=1&theme=dark
import React from "react";
import {
StyleSheet,
TextInput,
Text,
TouchableOpacity,
Image,
ScrollView
} from "react-native";
import { useForm, Controller } from "react-hook-form";
const AddAddress = () => {
const { control, handleSubmit, errors, reset } = useForm({
defaultValues: {
name: "",
email: ""
}
});
function submit(data) {
console.log(data);
}
return (
<ScrollView contentContainerStyle={styles.container}>
<Text style={styles.title}>React Hook Form</Text>
<Controller
control={control}
name="name"
render={({ onChange, value }) => (
<TextInput
placeholder="Name"
style={styles.input}
onChangeText={(value) => onChange(value)}
/>
)}
/>
<Controller
control={control}
name="email"
render={({ onChange, value }) => (
<TextInput
placeholder="Email"
style={styles.input}
onChangeText={(value) => onChange(value)}
/>
)}
/>
<TouchableOpacity onPress={handleSubmit(submit)}>
<Text style={styles.button}>Submit</Text>
</TouchableOpacity>
</ScrollView>
);
};
export default AddAddress;
It is because you are passing the onChange function dirctly, but it is a part of the field prop, so you should pass them as a named argument
...Controller
render={({
field: { onChange, onBlur, value, name, ref },
fieldState: { invalid, isTouched, isDirty, error },
}) => ( ...
Kindly have a look at the docs : https://react-hook-form.com/api/usecontroller/controller
Or pass in the value field, and use the field.onChange method.
This is the modified code.
The output on submit will be as follows after providing the inputs
{name: "sample", email: "sample#g,co"}
import React from "react";
import {
StyleSheet,
TextInput,
Text,
TouchableOpacity,
Image,
ScrollView
} from "react-native";
import { useForm, Controller } from "react-hook-form";
const AddAddress = () => {
const { control, handleSubmit, errors, reset } = useForm({
defaultValues: {
name: "",
email: ""
}
});
function submit(data) {
console.log(data);
}
return (
<ScrollView contentContainerStyle={styles.container}>
<Text style={styles.title}>React Hook Form</Text>
<Controller
control={control}
name="name"
// ------------ modified here
render={({field}) => (
<TextInput
placeholder="Name"
style={styles.input}
onChange = {(e)=>field.onChange(e)}
value = {field.value}
/>
)}
/>
<Controller
control={control}
name="email"
// ------------ modified here
render={({ field }) => (
<TextInput
placeholder="Email"
style={styles.input}
onChange = {(e)=>field.onChange(e)}
value = {field.value}
/>
)}
/>
<TouchableOpacity onPress={handleSubmit(submit)}>
<Text style={styles.button}>Submit</Text>
</TouchableOpacity>
</ScrollView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#282828",
alignItems: "center",
justifyContent: "center"
},
title: {
fontSize: 36,
marginBottom: 30,
marginTop: 16,
color: "white"
},
error: {
fontSize: 16,
color: "red",
marginTop: 16,
marginBottom: 16,
marginLeft: 36,
marginRight: 36
},
input: {
fontSize: 18,
borderWidth: 1,
padding: 12,
width: "80%",
borderRadius: 10,
backgroundColor: "white",
marginBottom: 16,
marginTop: 16
},
image: {
width: 120,
height: 120,
borderColor: "orange",
borderWidth: 2,
borderRadius: 100
},
button: {
fontSize: 20,
color: "white",
width: 120,
marginTop: 8,
borderRadius: 10,
backgroundColor: "#c01c00",
padding: 8,
textAlign: "center"
}
});
export default AddAddress;
I'm quite new to react native and trying to set up a search bar with search functionality. I'm trying to set it up where the list updates with each letter typed. The data is displayed fine but the error occurs when I try and type something into the search bar.
Full Error Message
https://ibb.co/Zd5hB52
Here is the file that is having issues
import { StyleSheet, Text, View, Button, StatusBar, ScrollView, TextInput } from "react-native";
import Icon from 'react-native-vector-icons/Ionicons';
import datas from "../components/CurrencyData"
import FavouritesList from "../components/FavouritesList";
const AddToFavourites = () => {
const state = {
datas: datas,
filter: datas
}
const [currencyFilter, setSearch] = useState(state.filter)
const getFlags = () => {
return currencyFilter.map(data => {
return <FavouritesList detail={data} key={data.id}/>
})
}
const searchCurrencies = (searchFor) => {
setSearch({
filterCurrency: datas.filter(i=>
i.name.toLowerCase().includes(searchFor.toLowerCase),
),
});
}
return (
<View style={styles.container}>
<View style= {styles.action}>
<Icon name="search" size={25}/>
<TextInput
style= {{flex: 1}}
placeholder= "Search..."
underlineColorAndroid="transparent"
onChangeText= {text => {searchCurrencies(text)}}
/>
</View>
<ScrollView>
<StatusBar backgroundColor="#1E90FF" barStyle="light-content"/>
{getFlags()}
</ScrollView>
</View>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
justifyContent: "center",
},
action: {
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
borderWidth: 2,
height: 50,
borderRadius: 30,
paddingLeft: "4%",
paddingRight: "4%",
margin: "3%"
},
})
export default AddToFavourites;```
[1]: https://i.stack.imgur.com/kWkHo.png
with hooks you don't pass the state object like setState, you just pass the new value
change
setSearch({
filterCurrency: datas.filter(i => i.name.toLowerCase().includes(searchFor.toLowerCase)),
});
to
setSearch( datas.filter(I =>i.name.toLowerCase().includes(searchFor.toLowerCase)));
I have a ScrollView component, and within it I have a form (<AppForm >) that works using Formik and Yup. This form has some input fields (<AppTextInput >). In the form I assign the keyboardType prop for each input field.
The problem is that the fields with keyboardType set to default scroll down the whole ScrollView component when you focus on it, like adding margin to the top of it. This only happens when the keyboardType is set to default.
If I focus on an input field with the keyboardType prop set to numeric, everything works fine.
Any idea of what am I doing wrong?
Here is a gif of what's exactly the problem:
https://giphy.com/gifs/djoHUBAKu9XGyu37OO
And here is my code:
AppFormField (Main screen)
function ActivityFormScreen({ navigation }) {
return (
<View style={styles.container}>
<ActivityIndicator
visible={
postActivityApi.loading ||
editActivityApi.loading ||
getTrabajosApi.loading ||
getCosechasApi.loading ||
getMaquinariasApi.loading
}
/>
<ScrollView style={{ paddingBottom: 500 }}>
<ActivityTitle
text="Información"
name="information-variant"
size={35}
/>
<AppForm
onSubmit={(form) => handleSubmit(form)}
validationSchema={validationShema}
initialValues={{
fecha: getFormValue("fecha"),
finca_id: getFormValue("finca_id"),
lote: getFormValue("lote"),
cosecha: getFormValue("cosecha"),
cultivos: getFormValue("cultivos"),
maquinaria: getFormValue("maquinaria"),
tiempo_actividad: getFormValue("tiempo_actividad"),
productos: getFormValue("productos"),
cantidad: getFormValue("cantidad"),
unidad: getFormValue("unidad"),
hectarea_trabajada: getFormValue("hectarea_trabajada"),
trabajos: getFormValue("trabajos"),
observaciones: getFormValue("observaciones"),
}}
>
<AppFormField
name="fecha"
holder="Fecha"
keyboardType="default"
placeholder="AAAA-MM-DD"
defaultValue={getFormValue("fecha")}
/>
<AppPickerField
name="finca_id"
holder="Granja"
data={context.allFarms} //Seleccionar el array de granjas
pickerPlaceholder="Seleccione una granja"
value={getFormValue("finca_id")}
/>
<AppFormField
name="lote"
holder="Lote"
keyboardType="numeric"
defaultValue={getFormValue("lote")}
/>
.
.
.
<SubmitButton title="Guardar" />
</AppForm>
</ScrollView>
</View>
);
}
const styles = StyleSheet.create({
container: {
backgroundColor: "white",
flex: 1,
justifyContent: "center",
marginHorizontal: 10,
// paddingTop: 50,
},
});
AppFormField
import React from "react";
import { useFormikContext } from "formik";
import { StyleSheet, View } from "react-native";
import AppTextInput from "../AppTextInput";
import ErrorMessage from "./ErrorMessage";
function AppFormField({ placeholder, name, width, holder, ...otherProps }) {
const { setFieldTouched, handleChange, errors, touched } = useFormikContext();
return (
<View style={styles.container}>
<AppTextInput
onBlur={() => setFieldTouched(name)}
onChangeText={handleChange(name)}
width={width}
holder={holder}
placeholder={placeholder}
{...otherProps}
/>
<ErrorMessage error={errors[name]} visible={touched[name]} />
</View>
);
}
const styles = StyleSheet.create({
container: {
marginBottom: 20,
marginHorizontal: 20,
},
});
export default AppFormField;
AppTextInput
import React from "react";
import { StyleSheet, View, TextInput, Text, Keyboard } from "react-native";
function AppTextInput({ placeholder = " ", holder, ...otherProps }) {
return (
<View style={styles.container}>
<Text style={styles.holder}>{holder}</Text>
<TextInput
style={styles.input}
placeholder={placeholder}
returnKeyLabel="Listo"
returnKeyType="done"
onSubmitEditing={Keyboard.dismiss}
{...otherProps}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
backgroundColor: "transparent",
},
holder: {
fontSize: 20,
textAlign: "left",
color: "#000",
opacity: 0.6,
width: "100%",
height: 30,
},
input: {
fontSize: 20,
borderBottomWidth: 1,
borderColor: "#D9D5DC",
width: "100%",
},
});
export default AppTextInput;
SOLVED:
For some reason my ScrollView component had the property paddingBottom set to 500, and just by removing it, I solved the issue.
Right now I am trying to make a Log In Page and I've been using React Native to do so. It works perfectly fine on a web browser but when I try it on my phone, onChange doesn't seem to change the state of the password and username.
import React from 'react';
import { TextInput, View, TouchableOpacity, Text } from 'react-native';
class LogIn extends React.Component {
constructor(props){
super(props);
this.state={
username: 'John Doe',
password: 'abc123'
}
}
loginChangeHandler = (event) =>{
this.setState({[event.target.name]: event.target.value});
}
loginButtonHandler = () =>{
alert('username: '+this.state.username+ ' Password: '+this.state.password)
}
render() {
return (
<View style = {{alignItems: 'center'}}>
<TextInput name = 'username' onChange = {this.loginChangeHandler}
placeholder = 'username'
style={{ width: 200, height: 55, borderColor: 'gray', borderWidth: 1 }}
/>
<Text>{'\n'}</Text>
<TextInput name = 'password' onChange = {this.loginChangeHandler} secureTextEntry={true}
placeholder = 'password'
style={{ width: 200, height: 55, borderColor: 'gray', borderWidth: 1 }}
/>
<Text>{'\n'}</Text>
<TouchableOpacity onPress = {this.loginButtonHandler} style = {{height: 45, width: 200, justifyContent: 'center', alignItems: "center", backgroundColor: 'green'}}>
<Text style = {{fontSize: 16, color: 'white'}}>LOG IN</Text>
</TouchableOpacity>
</View>
);
}
}
export default LogIn;
To use this inside of a function you must bind the function with this object. Other thing is there isn't direct name prop for TextInput component and event.target is not returning something you expected. onChange is called with { nativeEvent: { eventCount, target, text} }, then i suggest you to use onChangeText callback. This callback is called with only the value which you are typing.
Change your code this way.
render() {
return (
<View style = {{alignItems: 'center'}}>
<TextInput name = 'username' onChangeText= {(value) => this.setState({ username : value })}
placeholder = 'username'
style={{ width: 200, height: 55, borderColor: 'gray', borderWidth: 1 }}
/>
<Text>{'\n'}</Text>
<TextInput name = 'password' onChangeText={(value) => this.setState({ password : value })} secureTextEntry={true}
placeholder = 'password'
style={{ width: 200, height: 55, borderColor: 'gray', borderWidth: 1 }}
/>
<Text>{'\n'}</Text>
<TouchableOpacity onPress = {this.loginButtonHandler.bind(this)} style = {{height: 45, width: 200, justifyContent: 'center', alignItems: "center", backgroundColor: 'green'}}>
<Text style = {{fontSize: 16, color: 'white'}}>LOG IN</Text>
</TouchableOpacity>
</View>
);
}