I have an input through Formik
that takes in number, but even when it passes the Formik
validation, the resulting input is still categorized as string
.
<Formik
initialValues={{ price: '' }}
onSubmit={submitHandler}
validationSchema={yup.object().shape({
price: yup
.number()
.required(),
})}
>
{({ values, handleChange, errors, setFieldTouched, touched, isValid, handleSubmit }) => (
<View style={styles.form}>
<View style={styles.fieldset}>
<Text style={{ marginLeft: 40, marginVertical: 10 }}>
<Text style={{ color: '#FF5D4E'}}>* </Text>
Price
</Text>
<TextInput
value={values.price}
keyboardType = 'numeric'
onChangeText={handleChange('price')}
placeholder="Rental price of your item per day"
style={styles.textInput}
onBlur={() => setFieldTouched('price')}
/>
</View>
{touched.price && errors.price &&
<Text style={{ fontSize: 10, color: 'red' }}>{errors.price}</Text>
}
<TouchableOpacity
disabled={!isValid || loading}
onPress={handleSubmit}
style={styles.button}
>
<Text style={styles.buttonText}>Submit</Text>
</TouchableOpacity>
</View>
)}
</Formik>
When the price is entered, any non-number is met with a warning. However, when I console log the the value passed to the submitHandler
function, the typeof
shows the price value as a string.
I have an input through Formik
that takes in number, but even when it passes the Formik
validation, the resulting input is still categorized as string
.
<Formik
initialValues={{ price: '' }}
onSubmit={submitHandler}
validationSchema={yup.object().shape({
price: yup
.number()
.required(),
})}
>
{({ values, handleChange, errors, setFieldTouched, touched, isValid, handleSubmit }) => (
<View style={styles.form}>
<View style={styles.fieldset}>
<Text style={{ marginLeft: 40, marginVertical: 10 }}>
<Text style={{ color: '#FF5D4E'}}>* </Text>
Price
</Text>
<TextInput
value={values.price}
keyboardType = 'numeric'
onChangeText={handleChange('price')}
placeholder="Rental price of your item per day"
style={styles.textInput}
onBlur={() => setFieldTouched('price')}
/>
</View>
{touched.price && errors.price &&
<Text style={{ fontSize: 10, color: 'red' }}>{errors.price}</Text>
}
<TouchableOpacity
disabled={!isValid || loading}
onPress={handleSubmit}
style={styles.button}
>
<Text style={styles.buttonText}>Submit</Text>
</TouchableOpacity>
</View>
)}
</Formik>
When the price is entered, any non-number is met with a warning. However, when I console log the the value passed to the submitHandler
function, the typeof
shows the price value as a string.
- 2 I've never use yup, but in joi just using number() doesn't control the type but only the content. Try adding .strict() to the validation – Auticcat Commented Nov 22, 2019 at 11:18
- @Auticcat What's the difference between the type and content? – Kevvv Commented Nov 22, 2019 at 18:23
- For example number = 1 has content equal to 1 but has as type number. If you do number = “1” has content equal to 1 like before, but is a string. Doing strict will control that the content is a number but also control that the type is equal to number – Auticcat Commented Nov 22, 2019 at 18:26
2 Answers
Reset to default 6This is just happening while using Formik with React Native. In React for web you can set the input with type="number"
but in React Native you can't.
Even if you add keyboardType="numeric"
to <TextInput />
. In the other hand, if you use Yup (which I strongly remend) this is not checking for type, just for content this means "1"
may be interpreted as a number.
Solution:
import Formik from 'formik';
import * as yup from 'yup';
...
<Formik
initialValues={{ price: '' }}
validationSchema={yup.object().shape({ price: yup.number() })}
/>
{(values, setFieldValue, handleBlur) => (
<TextInput
value={values.price}
onChangeText={value => setFieldValue('price', parseFloat(value))}
onBlur={handleBlur('price')}
keyboardType="decimal-pad"
/>
)}
</Formik>
happy coding!
You can parse the string
value in onChangeText
like this:
{({ values, ...., setFieldValue }) => {
// parse string value to int
const parseAndHandleChange = (value, setFieldValue, id) => {
const parsed = parseInt(value, 10)
setFieldValue(id, parsed)
}
return (
<View>
{.....}
<TextInput
value={values.price}
keyboardType = 'numeric'
onChangeText={value => parseAndHandleChange(value, setFieldValue, 'price')}
placeholder="Rental price of your item per day"
style={styles.textInput}
onBlur={() => setFieldTouched('price')}
/>
</View>
)}
This is just an example, feel free to modify based on your use case. Hope it helps.