我正在使用Formik创建一个提醒表单,用于存储一些信息,包括日期和时间。我在表单中使用DateTimePicker
中的react-native-modal-datetime-picker
时遇到了问题。
我的主要目标是当用户按下日期或时间输入时,将显示DateTimePicker
。用户选择时间后,DateTimePicker
将把该值传递给输入并在屏幕上显示该输入。当用户按下“提交”按钮时,日志控制台将打印出values
的{{1}}道具
这是我的代码:
Formik
运行此代码时,日期和时间输入未显示之前在import React from 'react'
import {View, TouchableOpacity} from 'react-native'
import {Button, Input} from 'react-native-elements'
import ModalDropdown from 'react-native-modal-dropdown'
import DateTimePicker from 'react-native-modal-datetime-picker'
import {Formik} from 'formik'
import * as yup from 'yup'
export default class ReminderForm extends React.Component{
constructor(props){
super(props);
this.state = {
isDatePickerVisible: false,
isTimePickerVisible: false,
reminder: {
date: '',
time: '',
//...more properties go here
}
}
}
showDatePicker = () => {//show the picker for Date input
this.setState({ isDatePickerVisible: true });
};
hideDatePicker = () => {
this.setState({ isDatePickerVisible: false });
};
handleDatePicked = date => {
let newDate = new Date(date).toLocaleDateString();
this.setState(prevState=> ({
...prevState,
isDatePickerVisible: !prevState.isDatePickerVisible,
reminder: {
...prevState.reminder,
date: newDate
}
}));
console.log(this.state);
};
showTimePicker = () => {//show the picker for time input
this.setState({ isTimePickerVisible: true });
};
hideTimePicker = () => {
this.setState({ isTimePickerVisible: false });
};
handleTimePicked = time => {
let newTime = new Date(time).toLocaleTimeString();
this.setState(prevState=> ({
...prevState,
isTimePickerVisible: !prevState.isTimePickerVisible,
reminder: {
...prevState.reminder,
time: newTime
}
}))
console.log(this.state)
};
render(){
return(
<View style = {{flex:1}}>
<Formik initialValues = {this.state.reminder}
onSubmit={()=> console.log('Submitted')}
>
{
({values,handleChange,errors,setFieldTouched,touched,isValid,handleSubmit})=>(
<View style ={{flex:1, justifyContent:'space-around'}}>
<TouchableOpacity style ={{flex:1, marginTop: 10, marginBottom:10, backgroundColor:null}}
onPress={this.showDatePicker}>
<Input value = {values.date} inputContainerStyle={{height: '60%'}} onChangeText={handleChange('date')}
onBlur={()=>setFieldTouched('date')} label = "Date" labelStyle = {{fontSize: 15}}/>
</TouchableOpacity>
<DateTimePicker mode="date" isVisible={this.state.isDatePickerVisible}
onConfirm={this.handleDatePicked} onCancel={this.hideDatePicker}/>
<TouchableOpacity style ={{flex:1, marginTop: 10, marginBottom:10, backgroundColor:null}}
onPress={this.showTimePicker}>
<Input value = {values.time}
onChangeText={handleChange('time')} inputContainerStyle={{height: '60%'}}
onBlur={()=>setFieldTouched('time')} label = "Time" labelStyle = {{fontSize: 15}}/>
</TouchableOpacity>
<DateTimePicker mode="time" isVisible={this.state.isTimePickerVisible}
onConfirm={this.handleTimePicked} onCancel={this.hideTimePicker}/>
//..more inputs go here
<Button containerStyle = {{flex:1, marginTop: 10, marginBottom:0}} TouchableComponent={TouchableOpacity}
onPress={()=> console.log(values)} title = "Submit" titleStyle = {{fontSize: 15}}/>
</View>
)
}
</Formik>
</View>
)
}
}
中选择的值,并且在{{1}中提交表单DateTimePikcker
和date
属性时道具无效。然后,我尝试修复输入的属性:
time
这次,输入确实显示了我从values
中选择的值,但是当我提交表单 <TouchableOpacity style ={{flex:1, marginTop: 10, marginBottom:10, backgroundColor:null}}
onPress={this.showDatePicker}>
<Input value = {this.state.reminder.date} inputContainerStyle={{height: '60%'}} onChangeText={handleChange('date')}
onBlur={()=>setFieldTouched('date')} label = "Date" labelStyle = {{fontSize: 15}}/>
</TouchableOpacity>
属性时,它仍然返回null。问题是,当用户在DateTimePicker
中选择日期时,我不知道如何更改date
的{{1}}道具中的属性。你们可以帮我弄清楚吗?
另一个问题是values
道具在这里不起作用。我尝试将Formik
放在DateTimePicker
属性中(您可以在上面的代码中看到),但是它不起作用。
答案 0 :(得分:6)
下面是一个示例。注意使用了Formik的setFieldValue。
import React, { useState } from 'react';
import { Button, Text, View } from 'react-native';
import { Formik } from 'formik';
import DateTimePickerModal from 'react-native-modal-datetime-picker';
import moment from 'moment';
export default function Example() {
return (
<Formik initialValues={{ myDate: moment().format('YYYY-MM-DD') }} onSubmit={values => console.log(values)}>
{({ handleSubmit, values, setFieldValue }) => (
<MyForm values={values} setFieldValue={setFieldValue} handleSubmit={handleSubmit} />
)}
</Formik>
);
}
export const MyForm = props => {
const { handleSubmit, values, setFieldValue } = props;
const [isDatePickerVisible, setDatePickerVisibility] = useState(false);
const showDatePicker = () => {
setDatePickerVisibility(true);
};
const hideDatePicker = () => {
setDatePickerVisibility(false);
};
const handleConfirm = date => {
setFieldValue('myDate', moment(date).format('YYYY-MM-DD'))
hideDatePicker();
};
return (
<View>
<Text onPress={showDatePicker}>{moment(values.myDate).format('YYYY-MM-DD')}</Text>
<DateTimePickerModal
isVisible={isDatePickerVisible}
mode="date"
onConfirm={handleConfirm}
onCancel={hideDatePicker}
date={moment(values.myDate).toDate()}
/>
<Button title="Submit" onPress={handleSubmit} />
</View>
);
}
答案 1 :(得分:0)
我为您制作了example
。请参考并填写代码。
import React, { Component } from "react";
import { Button, View,TextInput } from "react-native";
import DateTimePicker from "react-native-modal-datetime-picker";
let date_pick;
export default class DateTimePickerTester extends Component {
constructor(props) {
super(props);
this.state = {
isDateTimePickerVisible: false,
reminder:{
date: "8/24/2009"
}
};
}
showDateTimePicker = () => {
date_pick = new Date(this.state.reminder.date);
this.setState({ isDateTimePickerVisible: true });
};
hideDateTimePicker = () => {
this.setState({ isDateTimePickerVisible: false });
};
handleDatePicked = date => {
console.log("A date has been picked: ", date);
this.hideDateTimePicker();
};
render() {
return (
<View style={{flex:1,justifyContent:"center",alignItems:"center"}}>
<Button title="Show DatePicker" onPress={this.showDateTimePicker} />
<DateTimePicker
isVisible={this.state.isDateTimePickerVisible}
onConfirm={this.handleDatePicked}
onCancel={this.hideDateTimePicker}
date={date_pick}
/>
<TextInput value = {this.state.reminder.date} style={{width:"80%",height:20,borderColor:"red",borderWidth:1}} />
</View>
);
}
}