React native 为什么当我将带有文本输入的视图提取到一个函数时,每次击键时键盘都会被关闭,而当我直接返回它时却不会?
我创建了一个FormInput组件,它用TextInput封装了一个视图:React native 为什么当我将带有文本输入的视图提取到一个函数时,每次击键时键盘都会被关闭,而当我直接返回它时却不会?,react-native,React Native,我创建了一个FormInput组件,它用TextInput封装了一个视图: <FormInput inputType="text" title={translate("Exam Name")} value={name} setValue={setName} ref={examNameRef} required /> 在FormInput中,我执行以下操作: if (inputType === 'text') { // return ( /
<FormInput inputType="text" title={translate("Exam Name")} value={name} setValue={setName} ref={examNameRef} required />
在FormInput中,我执行以下操作:
if (inputType === 'text') {
// return (
// <View style={[styles.button, { height: 90 }]} >
// <View style={{ flexDirection: 'row' }}>
// <Text style={[styles.fieldLabel, {}]}>{title}</Text>
// {required && <Text style={{ color: 'red' }}>{' *'}</Text>}
// </View>
// <View>
// {requiredValidationError ?
// <Text style={[styles.fieldValue, { borderColor: 'red', color: 'red' }]}>{'Campo Obrigatório'}</Text>
// :
// <TextInput style={[styles.fieldValue]} value={value} onChangeText={setValue} />
// }
// </View>
// </View>
// )
return <InputText />
if(inputType=='text'){
//返回(
//
//
//{title}
//{必需&&{'*'}}
//
//
//{requiredValidationError?
//{'Campo Obrigatório'}
// :
//
// }
//
//
// )
返回
函数InputText的代码与上面注释的代码相同:
function InputText() {
return (
<View style={[styles.button, { height: 90 }]} >
<View style={{ flexDirection: 'row' }}>
<Text style={[styles.fieldLabel, {}]}>{title}</Text>
{required && <Text style={{ color: 'red' }}>{' *'}</Text>}
</View>
<View>
{requiredValidationError ?
<Text style={[styles.fieldValue, { borderColor: 'red', color: 'red' }]}>{'Campo Obrigatório'}</Text>
:
<TextInput style={[styles.fieldValue]} value={value} onChangeText={setValue} />
}
</View>
</View>
)
}
函数InputText(){
返回(
{title}
{必需&&{'*'}}
{requiredValidationError?
{'Campo Obrigatório'}
:
}
)
}
当我像这样使用它时,我的键盘在每次按键时都会被关闭,但是当我取消注释上面的注释部分并直接返回视图而不是将其放在函数中时,这个错误就不会发生了。有什么问题吗
下面是完整的FormInput.js:
import React, { useState, useEffect, useRef, forwardRef, useImperativeHandle } from 'react';
import { Text, Pressable, View, TextInput, SafeAreaView, TouchableOpacity, Platform, ActivityIndicator, StyleSheet, Switch } from 'react-native';
import { useNavigation, useRoute, useTheme } from '@react-navigation/native';
import { translate } from '../../translate';
import Page from '../../components/Page';
import Picker from '../../components/Picker';
import Modal from '../../components/Modal';
import Button from '../../components/Button';
import DateTimePicker from '@react-native-community/datetimepicker';
import Toast from 'react-native-simple-toast';
import moment from 'moment';
import Icon from 'react-native-vector-icons/Ionicons';
Icon.loadFont();
const FormInput = forwardRef(({ inputType, title, value, setValue, required, maxLength }, ref) => {
const [modalVisible, setModalVisible] = useState(false);
const [internalValue, setInternalValue] = useState(value);
const [dateTimePickerMode, setDateTimePickerMode] = useState("date");
const [date, setDate] = useState(new Date());
const [requiredValidationError, setRequiredValidationError] = useState(false);
const inputRef = useRef();
useImperativeHandle(ref, () => ({
validate() {
if (required) {
if (internalValue) {
setRequiredValidationError(false)
} else {
setRequiredValidationError(true)
}
}
},
error: requiredValidationError
}));
const onChangeDate = (event, newDate) => {
if (event.type === "dismissed") {
setDateTimePickerMode("date")
setModalVisible(false);
return;
}
const dateWithTime = new Date(date);
if (dateTimePickerMode === 'date') {
setModalVisible(true);
setDate(newDate || new Date());
setDateTimePickerMode('time');
} else {
setModalVisible(false);
dateWithTime.setHours(newDate.getHours());
dateWithTime.setMinutes(newDate.getMinutes());
setDateTimePickerMode('date');
setValue(dateWithTime);
}
}
function InputSwitch() {
return (
<View style={[styles.button, { paddingRight: 15 }]} >
<Text style={[styles.fieldLabel, { marginBottom: 10 }]}>{title}</Text>
<View style={{ marginRight: 30 }}>
<Switch
style={{ transform: [{ scaleX: Platform.select({ ios: 0.8, android: 1.3 }) }, { scaleY: Platform.select({ ios: 0.8, android: 1.3 }) }] }}
thumbColor={"#f4f3f4"}
onValueChange={setValue}
value={value}
/>
</View>
</View>
)
}
function InputText() {
return (
<View style={[styles.button, { height: 90 }]} >
<View style={{ flexDirection: 'row' }}>
<Text style={[styles.fieldLabel, {}]}>{title}</Text>
{required && <Text style={{ color: 'red' }}>{' *'}</Text>}
</View>
<View>
{requiredValidationError ?
<Text style={[styles.fieldValue, { borderColor: 'red', color: 'red' }]}>{'Campo Obrigatório'}</Text>
:
<TextInput style={[styles.fieldValue]} value={value} onChangeText={setValue} />
}
</View>
</View>
)
}
function InputNumber() {
return (
<View style={[styles.button, { height: 90 }]} >
<View style={{ flexDirection: 'row' }}>
<Text style={[styles.fieldLabel, {}]}>{title}</Text>
{required && <Text style={{ color: 'red' }}>{' *'}</Text>}
</View>
<View>
<Text style={[styles.fieldValue, { borderColor: requiredValidationError ? 'red' : 'grey', color: requiredValidationError ? 'red' : 'grey' }]}>{requiredValidationError ? 'Campo Obrigatório' : value}</Text>
</View>
</View>
)
}
function InputDate() {
return (
<View>
{inputType === 'date' && modalVisible && (
<DateTimePicker
testID="dateTimePicker"
value={internalValue ? new Date(internalValue) : new Date()}
is24Hour={true}
mode={dateTimePickerMode}
onChange={onChangeDate}
/>
)}
<Pressable style={[styles.button, { height: 90 }]} onPress={() => setModalVisible(true)} >
<View style={{ flexDirection: 'row' }}>
<Text style={[styles.fieldLabel, {}]}>{title}</Text>
{required && <Text style={{ color: 'red' }}>{' *'}</Text>}
</View>
<Text style={styles.fieldValue}>{value ? moment(value).format('DD/MM/yyyy HH:mm') : ''}</Text>
</Pressable>
</View>
)
}
if (inputType === 'text') {
// return (
// <View style={[styles.button, { height: 90 }]} >
// <View style={{ flexDirection: 'row' }}>
// <Text style={[styles.fieldLabel, {}]}>{title}</Text>
// {required && <Text style={{ color: 'red' }}>{' *'}</Text>}
// </View>
// <View>
// {requiredValidationError ?
// <Text style={[styles.fieldValue, { borderColor: 'red', color: 'red' }]}>{'Campo Obrigatório'}</Text>
// :
// <TextInput style={[styles.fieldValue]} value={value} onChangeText={setValue} />
// }
// </View>
// </View>
// )
return <InputText />
} else if (inputType === 'number') {
return <InputNumber />
} else if (inputType === 'switch') {
return <InputSwitch />
} else if (inputType === 'date') {
return <InputDate />
} else {
return <Text style={{ backgroundColor: 'orange', textAlign: 'center', padding: 10, margin: 10 }}>Input do tipo {inputType} não está implementado</Text>
}
})
const styles = StyleSheet.create({
container: {
backgroundColor: '#A7A6A6',
marginBottom: 100
},
header: {
backgroundColor: '#FF000010',
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
paddingHorizontal: 16,
paddingVertical: Platform.select({ ios: 10, android: 10 })
},
title: {
flex: 1,
fontSize: 32,
color: '#626262',
fontWeight: 'bold',
backgroundColor: '#00FF0010',
},
modalView: {
marginVertical: 230,
marginHorizontal: 20,
backgroundColor: "white",
borderRadius: 20,
padding: 35,
alignItems: "center",
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2
},
shadowOpacity: 0.25,
shadowRadius: 4,
elevation: 5
},
button: {
padding: 5
},
fieldLabel: {
color: "grey",
fontWeight: "bold",
textAlign: "left"
},
fieldValue: {
color: "black",
textAlign: "right",
borderBottomWidth: 1,
paddingTop: 10,
paddingRight: 10,
paddingBottom: 5,
textAlign: 'right',
borderColor: 'grey',
},
modalText: {
marginBottom: 15,
textAlign: "center"
},
textInput: {
borderWidth: 0,
paddingHorizontal: 20,
fontSize: 16,
marginBottom: 4,
color: '#626262',
borderRadius: 0,
borderBottomWidth: 1,
borderColor: '#626262',
width: 300,
textAlign: 'center'
},
});
export default FormInput;
import React,{useState,useffect,useRef,forwardRef,useImperialiveHandle}来自“React”;
从“react native”导入{Text、Pressable、View、TextInput、SafeAreaView、TouchableOpacity、Platform、ActivityIndicator、StyleSheet、Switch};
从'@react-navigation/native'导入{useNavigation,useRoute,useTheme};
从“../../translate”导入{translate};
从“../../components/Page”导入页面;
从“../../components/Picker”导入选择器;
从“../../components/Modal”导入模态;
从“../../components/Button”导入按钮;
从“@react native community/DateTimePicker”导入DateTimePicker;
从“react native simple Toast”导入Toast;
从“力矩”中导入力矩;
从“反应本机矢量图标/离子图标”导入图标;
Icon.loadFont();
const FormInput=forwardRef({inputType,title,value,setValue,required,maxLength},ref)=>{
const[modalVisible,setModalVisible]=使用状态(false);
常量[internalValue,setInternalValue]=使用状态(值);
常量[dateTimePickerMode,setDateTimePickerMode]=useState(“日期”);
const[date,setDate]=useState(new date());
const[requiredValidationError,setRequiredValidationError]=useState(false);
const inputRef=useRef();
使用命令式句柄(参考,()=>({
验证(){
如果(需要){
如果(内部值){
setRequiredValidationError(错误)
}否则{
setRequiredValidationError(真)
}
}
},
错误:requiredValidationError
}));
const onChangeDate=(事件,newDate)=>{
如果(event.type==“已解除”){
setDateTimePickerMode(“日期”)
setModalVisible(假);
返回;
}
const dateWithTime=新日期(日期);
如果(dateTimePickerMode=='date'){
setModalVisible(真);
设置日期(newDate | | newDate());
setDateTimePickerMode(“时间”);
}否则{
setModalVisible(假);
dateWithTime.setHours(newDate.getHours());
dateWithTime.setMinutes(newDate.getMinutes());
setDateTimePickerMode(“日期”);
设置值(dateWithTime);
}
}
函数输入开关(){
返回(
{title}
)
}
函数InputText(){
返回(
{title}
{必需&&{'*'}}
{requiredValidationError?
{'Campo Obrigatório'}
:
}
)
}
函数InputNumber(){
返回(
{title}
{必需&&{'*'}}
{requiredValidationError?'Campo Obrigatório':value}
)
}
函数InputDate(){
返回(
{inputType=='date'&&modalVisible&&(
)}
setModalVisible(真)}>
{title}
{必需&&{'*'}}
{value?力矩(value).format('DD/MM/yyyy HH:MM'):''}
)
}
如果(inputType==='text'){
//返回(
//
//
//{title}
//{必需&&{'*'}}
//
//
//{requiredValidationError?
//{'Campo Obrigatório'}
// :
//
// }
//
//
// )
返回
}else if(inputType==‘number’){
返回
}else if(输入类型===‘开关’){
返回
}else if(inputType=='date'){
返回
}否则{
返回输入do tipo{inputType}não estáimplementado
}
})
const styles=StyleSheet.create({
容器:{
背景颜色:“#A7A6A6”,
marginBottom:100
},
标题:{
背景颜色:“#FF000010”,
flexDirection:'行',
为内容辩护:“中心”,
对齐项目:“居中”,
水平方向:16,
paddingVertical:Platform.select({ios:10,android:10})
},
标题:{
弹性:1,
字体大小:32,
颜色:'#6262',
fontWeight:'粗体',
背景颜色:“#00FF0010”,
},
莫达尔维:{
澳门:230,
marginHorizontal:20,
背景颜色:“白色”,
边界半径:20,
填充:35,
对齐项目:“中心”,
阴影颜色:“000”,
阴影偏移:{
宽度:0,
身高:2
},
阴影不透明度:0.25,
阴影半径:4,
立面图:5
},
按钮:{
填充:5
},
字段标签:{
颜色:“灰色”,
fontWeight:“粗体”,
textAlign:“左”
},
字段值:{
颜色:“黑色”,
textAlign:“对”,
边界宽度:1,
paddingTop:10,
paddingRight:10,
填充底部:5,
textAlign:'右',
边框颜色:“灰色”,
},
modalText:{
marginBottom:15,
textAlign:“居中”
},
文本输入:{
边框宽度:0,
水平方向:20,
尺寸:16,
marginBottom:4,
颜色:'#6262',
边界者
return (
<>
<Page type="static" title={'Avaliação'} subtitle={'Editar'}>
<ScrollView style={{ flexGrow: 0.8, paddingHorizontal: 5}} keyboardShouldPersistTaps="always">
<FormInput inputType="text" title={translate("Exam Name")} value={name} setValue={setName} ref={examNameRef} required />
<FormInput inputType="text" title={translate("Code")} value={code} setValue={setCode} maxLength={8} ref={examCodeRef} required />
<FormInput inputType="number" title={translate("Max Grade")} value={maxGrade} setValue={setMaxGrade} />
<FormInput inputType="number" title={translate("Weight")} value={weight} setValue={setWeight} ref={examWeightRef} required />
<FormInput inputType="date" title={translate("Start Date")} value={startDate} setValue={setStartDate} />
<FormInput inputType="date" title={translate("End Date")} value={endDate} setValue={setEndDate} />
<FormInput inputType="switch" title={translate("Ignore Formula")} value={ignoreFormula} setValue={setIgnoreFormula} />
</ScrollView>
</Page>
<View style={{}}>
<Button style={[styles.button, {}]} textStyle={styles.buttonText} title={translate('Save')} onPress={() => saveExam()} requestFeedback />
</View>
</>
);