一个表单没有良好的 keyboard 操作,怎麽能说是一个好表单!!!!
接续 Day23 + Day24
到目前为止遇到三个问题 :
- 键盘上的 next go 要做什麽用呢?
- 刻完画面竟然被键盘挡住了 :(
- 人家键盘都可以自己收起来 我为什麽不行?
今天来处理 keyboard 右下角的 next and go 设定
前两天的表单页面让我们来前让我们来前情提要一下吧~
有几个选项可以放在里面分别为 cross-platform 跟一些符合 OS-specific.像是 email input 里我们写上"next" 这个选项,他的意思是他会将 focus 移动到下一个 input,"go" 这个选项会启动 submit 的 function,而这些事件需要另外来写,所以就是我们今天所要学习的项目唷!
<Input
label='mail'
placeholder='Enter your email'
autoCapitalize='none'
autoCompleteType='email'
keyboardType='email-address'
keyboardAppearance='dark'
// here
returnKeyType='next'
returnKeyLabel='next'
/>
import React, { useRef } from 'react';
const phone = useRef(null);
const email = useRef(null);
// 只有第一个input不需要
<Input
// ...
label='Name'
returnKeyType='next'
returnKeyLabel='next'
// 加入
onSubmitEditing={() => mail.current?.focus()}
/>
<Input
// 加入
ref={mail}
label='Mail'
// ...
returnKeyType='next'
returnKeyLabel='next'
// 加入
onSubmitEditing={() => phone.current?.focus()}
/>
<Input
// 加入
ref={phone}
label="Phone"
// ...
returnKeyType='next'
returnKeyLabel='next'
/>
接着你会发现 simulator 为 warning,这是因为我们的 Input 是客制的,所以我们需要做一些处理。
引入 forwardRef 於 components/ Input.js
forwardRef 是一个自动将 ref 传给一个 children component 的技术,而我的现在需要的就是将 ref 从 Formik.js 传递到 Input.
import React, { forwardRef } from 'react';
import React, {forwardRef} from 'react';
import {TextInput as RNTextInput, View, StyleSheet, Text} from 'react-native';
const Input =
// forwardRef 包起来 start
forwardRef(
({label, error, touched, ...otherProps}, ref) => {
const validationColor = !touched ? '#223e4b' : error ? '#FF5A5F' : '#223e4b';
return (
<View style={[styles.input, {borderColor: validationColor}]}>
<View style={{padding: 8}}>
<Text>{label}</Text>
</View>
<View style={{flex: 1}}>
<RNTextInput
underlineColorAndroid="transparent"
placeholderTextColor="#ccc"
// 加入 ref
ref={ref}
{...otherProps}
/>
</View>
</View>
);
}
);
// forwardRef 包起来 end
const styles = StyleSheet.create({
input: {
flexDirection: 'row',
alignItems: 'center',
height: 48,
borderRadius: 8,
borderWidth: StyleSheet.hairlineWidth,
padding: 8,
marginVertical: 10,
},
});
export default Input;
现在按下 "next" 按钮,他将会 focus 下一个 input!
上面处理好 "next" 按钮,现在来处理"go"按钮
onSubmitEditing={() => handleSubmit()}
import React, {useRef} from 'react';
import {StyleSheet, View, Text, ScrollView} from 'react-native';
import {fonts} from '@src/constants';
import {useFormik} from 'formik';
import Input from '../components/Input';
import Button from '../components/Button';
import {object as yupObject, string as yupString, ValidationError} from 'yup';
const Formik = () => {
const phone = useRef(null);
const email = useRef(null);
const phoneRegExp =
/^((\\+[1-9]{1,4}[ \\-]*)|(\\([0-9]{2,3}\\)[ \\-]*)|([0-9]{2,4})[ \\-]*)*?[0-9]{3,4}?[ \\-]*[0-9]{3,4}?$/;
const Schema = yupObject().shape({
name: yupString().required('Required'),
email: yupString().email('Invalid email').required('Required'),
phone: yupString()
.matches(phoneRegExp, 'Phone number is not valid')
.required('Required'),
});
const {handleChange, handleSubmit, handleBlur, values, errors, touched} =
useFormik({
validationSchema: Schema,
initialValues: {name: '', email: '', phone: ''},
onSubmit: values =>
alert(
`Name: ${values.name},Email: ${values.email}, phone: ${values.phone}`,
),
});
return (
<ScrollView style={styles.container}>
<View style={styles.textBox}>
<Text style={[styles.text, fonts.h1]}>欢迎来到卡卡塔罗</Text>
<Text style={(fonts.p, styles.textContent)}>
如果您有什麽需要或着回馈欢迎留言也或着想预约算塔罗牌也欢迎留言,谢谢您
</Text>
</View>
<View style={styles.formBox}>
<Input
onChangeText={handleChange('name')}
label="Name"
placeholder="Enter your name"
autoCapitalize="none"
autoCompleteType="email"
keyboardType="default"
keyboardAppearance="dark"
onBlur={handleBlur('name')}
error={errors.name}
touched={touched.name}
returnKeyType="next"
returnKeyLabel="next"
onSubmitEditing={() => email.current?.focus()}
/>
<Input
ref={email}
onChangeText={handleChange('email')}
label="Mail"
placeholder="Enter your email"
autoCapitalize="none"
autoCompleteType="email"
keyboardType="email-address"
keyboardAppearance="dark"
onBlur={handleBlur('email')}
error={errors.email}
touched={touched.email}
returnKeyType="next"
returnKeyLabel="next"
onSubmitEditing={() => phone.current?.focus()}
/>
<Input
ref={phone}
onChangeText={handleChange('phone')}
label="Phone"
placeholder="Enter your phone"
autoCompleteType="phone-pad"
autoCapitalize="none"
keyboardAppearance="dark"
onBlur={handleBlur('phone')}
error={errors.phone}
touched={touched.phone}
returnKeyType="go"
returnKeyLabel="go"
onSubmitEditing={() => handleSubmit()}
/>
<Button label="submit" color="maroon" onPress={handleSubmit} />
</View>
</ScrollView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'rgb(246,246,246)',
paddingHorizontal: 20,
},
textBox: {
justifyContent: 'center',
alignItems: 'center',
paddingVertical: 50,
},
textTitle: {color: '#aaa'},
textContent: {color: '#aaa', lineHeight: 20, marginTop: 10},
formBox: {
width: '100%',
alignItems: 'center',
justifyContent: 'center',
},
input: {
width: '100%',
textAlign: 'center',
borderWidth: 1,
borderColor: '#ddd',
padding: 10,
fontSize: 18,
margin: 10,
},
errorText: {
textAlign: 'center',
color: 'crimson',
marginBottom: 10,
},
});
export default Formik;
Formik 搭配 Yup 的验证是一个简单又容易了解的方法,Formik 的不断的更新连 Hook 的方式都有!Yup API 也提供了很多验证给表单元件!以及最後教使用 ref 来控制 keyboard,虽然这个设定并不是必须的,但这样一用,感觉也提高了使用者的体验!
到现在有没有发现
下一章节就继续来解决 keyboard 系列的问题噜!
Day 25 done~~~ 请多多指教
<<: DAY 28 Image message(图片讯息)
>>: DAY 28『 使用相机拍照 』 ImagePicker - Part2
Map是JavaScript ES6中新增的资料结构 ,类似於object ,不过Map还是跟ob...
可以使用ContentProvider将资料库分享给其他应用程序共享资讯,或从其他应用程序操作资料 ...
小弟我在去年有分享了 Distributed Tracing 分布式链路追踪简介 主要讲到Distr...
阵列的基本介绍 简单来说是存放一组资料集 阵列 会使用 [ ] 前後包住资料集 下面的范例意思是 d...
17 - Configatron Rails 内时常会用到共用的连结、字串、数字等 config,除...