简体   繁体   English

两次使用 React Native 日期时间选择器会报错?

[英]Using react native date time picker twice gives an error?

I use expo's datetime picker and it works perfectly fine if I click on it only once.我使用 expo 的日期时间选择器,如果我只单击一次它就可以正常工作。 If I click on it twice it gives me the following error:如果我点击它两次,它会给我以下错误:

TypeError: value.getTime is not a function. (In 'value.getTime()', 'value.getTime' is undefined) TypeError: value.getTime is not a function. (In 'value.getTime()', 'value.getTime' is undefined)

This error is located at: in RNDateTimePicker (at MyDateTimePicker.js:52)此错误位于:在 RNDateTimePicker 中(在 MyDateTimePicker.js:52)

This is my date time picker:这是我的日期时间选择器:

import React, { useState, useEffect } from 'react';
import { View, Text, TextInput, Image, Button, StyleSheet, TouchableOpacity } from 'react-native';
import DateTimePicker from '@react-native-community/datetimepicker';
import Moment from 'moment';

export default function MyDateTimePicker(props) {
  console.log("my date time picker props: ", props);
  const title = props.title;
  const [date, setDate] = useState(new Date());
  const [time, setTime] = useState(new Date());
  const [mode, setMode] = useState('date');
  const [show, setShow] = useState(false);
  const [text, setText] = useState(Moment(date).format('DD MMM YYYY HH:mm'));

  const onChange = (event, selectedValue) => {
    setShow(Platform.OS === 'ios');
    if (mode == 'date') {
     const currentDate = selectedValue || new Date();
     setDate(new Date(currentDate));
     setMode('time');
     setShow(Platform.OS !== 'ios'); // to show time
   } else {
     const currentTime = selectedValue || new Date();
     setDate(date.setTime(currentTime.getTime()));
     setShow(Platform.OS === 'ios'); // to hide back the picker
     setMode('date'); // defaulting to date for next open
   }
   props.updateDate(date);
  };

  const showMode = (currentMode) => {
    setShow(true);
    setMode(currentMode);
  };

  const showDatepicker = () => {
    console.log("show date picker");
    showMode('date');
  };

  const showTimepicker = () => {
    console.log("show time picker");
    showMode('time');
  };

  return(
    <View style={styles.viewStyle}>
      <TouchableOpacity onPress={showDatepicker}>
        <Text style={styles.inputStyle}>{text}</Text>
      </TouchableOpacity>
      {show && (
        <DateTimePicker
          value={date}
          mode={mode}
          is24Hour={true}
          display="default"
          onChange={onChange}
          minimumDate={new Date()}
          showTimeSelect
        />
      )}
    </View>
  )
}

And this is how I use it:这就是我使用它的方式:

<MyDateTimePicker updateDate={(date) => this.handleDate(date)} />

Where在哪里

handleDate(date) {
    this.setState({date: date});
  }

Again, if I click on the date-time picker only once, it all works fine, but if I try to select second date it breaks and I dont see why.同样,如果我只单击一次日期时间选择器,一切正常,但如果我尝试 select 第二个日期,它会中断,我不明白为什么。

The problem is here:问题在这里:

 setDate(date.setTime(currentTime.getTime()));

setTime returns a number of seconds passed from 01.01.1970 (which is when the world was created from a javascript developers' perspective), but the data picker expects a Date, not a Number, so it attempts to call getTime on a number, which doesn't go well. setTime返回从 01.01.1970(从 javascript 开发人员的角度创建世界的时间)经过的秒数,但数据选择器需要一个日期,而不是数字,因此它尝试在一个数字上调用getTime ,这go 不是很好。

I'm not familiar with this particular data picker, but if you're certain it loses the date part when in the 'time' mode try我不熟悉这个特定的数据选择器,但如果您确定它在“时间”模式下会丢失日期部分,请尝试

setDate(new Date(date.getTime()+currentTime.getTime()));

if that moves you too far into the future setDate(currentTime) might be enough (that applies to the 'time' mode only, 'date' part is fine)如果这让你离未来太远setDate(currentTime)可能就足够了(仅适用于“时间”模式,“日期”部分很好)

I was completely stumped on this same error for some time using the react-native-datetimepicker library.使用 react-native-datetimepicker 库一段时间以来,我完全被同样的错误所困扰。

The way it worked for me was I manually created the date in the required format and passed it to the date picker.它对我有用的方式是我以所需格式手动创建日期并将其传递给日期选择器。 Using moment().toISOString() did not work for me for some reason, although the format is the same as what comes out of the date picker after you change the date or time there.由于某种原因,使用 moment().toISOString() 对我不起作用,尽管格式与您更改日期或时间后日期选择器的格式相同。

The code looks roughly like this:代码大致如下:

const [customDate, setCustomDate] = useState(null);

useEffect(() => {
  const year = new Date().getFullYear();
  const month = new Date().getMonth();
  const date = new Date().getDate();
  const currentTime = new Date(year, month, date, 8, 11, 0);

  setCustomDate(currentTime);
}, []);

const selectDate = (event, selectedDate) => {
  const date = selectedDate || customDate;
  setCustomDate(date);
};

<DateTimePicker mode="date" value={customDate} onChange={selectDate} />

For class component datetimepicker对于 class 组件 datetimepicker

 class Productdetails extends Component {
                  constructor(props) {
                    super();
                this.state = {
            rentStartDate: new Date(),
                      startDate: "",
                      endDate: "",
                      mode: false,}
        this.onChangeStart = this.onChangeStart.bind(this);
        }
     onChangeStart(event, selectedDate) {
        let currentDate = selectedDate || this.state.rentStartDate;
        this.setState({ show: Platform.OS === "ios", rentStartDate: currentDate });
        let mydate = JSON.stringify(currentDate)
          .split("T")[0]
          .trim()
          .replace('"', "");
    
        this.setState({ startDate: mydate });
      }
     showMode(currentMode) {
        this.setState({
          show: true,
          mode: currentMode,
        });
      }
    
    return(<View style={{ flex: 1}}>
                  <Text style={{ textAlign: "center" }}>Start Date</Text>
                  <View
                    style={{
                      flex: 1,
                      flexDirection: "row",
                      justifyContent: "space-between",
                      alignItems: "center",
                      marginBottom: 5,
                      height: 40,
                      borderRadius: 2,
                      color: "black",
                      borderColor: "rgba(38, 38, 38,0.8)",
                      borderWidth: 1,
                      backgroundColor: "white",
                      paddingEnd: 5,
                    }}
                  >
                    <Text
                      style={{
                        fontSize: 14,
                        paddingLeft: 5,
                        backgroundColor: "white",
                        color: "black",
                      }}
                    >
                      {this.state.startDate}
                    </Text>
                    <TouchableHighlight onPress={() => this.showMode("date")}>
                      <Image
                        source={require("../images/calender.png")}
                        style={{ height: 24, width: 24 }}
                      />
                    </TouchableHighlight>
                    <Overlay
                      isVisible={this.state.show}
                      onBackdropPress={() => {
                        this.setState({ show: false });
                      }}
                    >
                      <DateTimePicker
                        testID="dateTimePicker"
                        value={this.state.rentStartDate}
                        mode={this.state.mode} //The enum of date, datetime and time
                        placeholder="select date"
                        format="DD-MM-YYYY"
                        confirmBtnText="Confirm"
                        cancelBtnText="Cancel"
                        timeZoneOffsetInMinutes={undefined}
                        modalTransparent={false}
                        animationType={"fade"}
                        display="default"
                        onChange={this.onChangeStart}
                        style={{ width: 320, backgroundColor: "white" }}
                      />
                    </Overlay>
                  </View>
                  <View></View>
                </View>)
export default React.memo(Productdetails);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM