【问题标题】:How to update selected date and time in task update?如何在任务更新中更新选定的日期和时间?
【发布时间】:2021-09-07 13:55:50
【问题描述】:

我最近开始研究 react native 并且在使用 datetimepicker 时遇到了困难,因为 DatePickerAndroid 和 TimePickerAndroid 已被弃用

在我的任务视图中,我正在导入已分解的 DateTimePickerInput 组件,以使其更具动态性。在任务寄存器中,它使用文档程序集完美地工作。但是要更新一个已经注册的任务,它不会更新输入或保存,指责如下错误:

(node:17560) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode).

任务视图索引:

import React, {useState, useEffect} from "react";
import {
    View,
    ScrollView,
    Text,
    Image,
    TextInput,
    KeyboardAvoidingView,
    TouchableOpacity,
    Switch,
    Alert,
    ActivityIndicator
} from "react-native";
import * as Network from 'expo-network';
//COMPONENTES
import Header from "../../components/Header";
import Footer from "../../components/Footer";
import styles from "./styles";
import DateTimeInput from "../../components/DateTimeInput";
import DateTimePickerInput from '../../components/DateTimePickerInput';
//ICONES
import typeIcons from "../../utils/typeIcons";
//API
import api from "../../services/api";


export default function Task({navigation}) {
    const [id, setId] = useState();
    const [done, setDone] = useState(false);
    const [type, setType] = useState();
    const [title, setTitle] = useState();
    const [description, setDescription] = useState();
    const [date, setDate] = useState();
    const [hour, setHour] = useState();
    const [macaddress, setMacaddress] = useState();
    const [load, setLoad] = useState(true);

    async function SaveTask() {
        if (!title)
            return Alert.alert('Defina o nome da tarefa!');
        if (!description)
            return Alert.alert('Defina a descrição da tarefa!');
        if (!type)
            return Alert.alert('Escolha um tipo para a tarefa!');
        if (!date)
            return Alert.alert('Escolha uma data para tarefa!');
        if (!hour)
            return Alert.alert('Escolha uma hora para tarefa!');

        if (id) {
            await api.put(`/task/${id}`, {
                macaddress,
                done,
                type,
                title,
                description,
                when: `${date}T${hour}.000`
            }).then((response) => {
                navigation.navigate('Home');
            }).catch((error) => {
                console.error(error);
            });
        } else {
            await api.post('/task', {
                macaddress,
                type,
                title,
                description,
                when: `${date}T${hour}.000`
            }).then((response) => {
                navigation.navigate('Home');
            }).catch((error) => {
                console.error(error);
            });
        }
    }

    async function LoadTask() {
        await api.get(`/task/${id}`).then((response) => {
            setLoad(true);
            setDone(response.data.done);
            setType(response.data.type);
            setTitle(response.data.title);
            setDescription(response.data.description);
            setDate(response.data.when);
            setHour(response.data.when);
        }).catch((error) => {
            console.error(error);
        })
    }

    async function getMacAddress() {
        //TODO: change to react-native-device-info
        await Network.getMacAddressAsync().then(mac => {
            setMacaddress(mac);
            setLoad(false);
        });
    }


    useEffect(() => {
        getMacAddress();
        if (navigation.state.params) {
            setId(navigation.state.params.idTask);
            LoadTask().then(() => setLoad(false));
        }

    }, [macaddress]);

    return (
        <KeyboardAvoidingView /*behavior='padding'*/ style={styles.container}>
            <Header showBack={true} navigation={navigation}/>
            {
                load ?
                    <ActivityIndicator color='#EE6B26' size={50} style={{marginTop: 250}}/>
                    :
                    <ScrollView style={{width: '100%'}}>
                        <ScrollView horizontal={true} showsHorizontalScrollIndicator={false}
                                    style={{marginVertical: 10}}>
                            {
                                typeIcons.map((icon, index) => (
                                    icon !== null &&
                                    <TouchableOpacity onPress={() => setType(index)}>
                                        <Image key={index} source={icon}
                                               style={[styles.imageIcon, type && type !== index && styles.typeIconInative]}/>
                                    </TouchableOpacity>
                                ))
                            }
                        </ScrollView>

                        <Text style={styles.label}>Título</Text>
                        <TextInput style={styles.input} maxLength={30} placeholder='Lembre-me de fazer...'
                                   onChangeText={(text) => setTitle(text)} value={title}/>

                        <Text style={styles.label}>Detalhes</Text>
                        <TextInput style={styles.inputArea} maxLength={200} multiline={true}
                                   placeholder='Detalhes da atividade que eu tenho que lembrar...'
                                   onChangeText={(text) => setDescription(text)} value={description}/>
                        {/*
                    ANDROID e IOS:
                        Para os antigos DatePickerAndroid e TimePickerAndroid utilizar os seguintes inputs:
                         <DateTimeInput type={'date'} save={setDate}/>
                         <DateTimeInput type={'hour'} save={setHour}/>
                */}
                        <DateTimePickerInput type={'date'} save={setDate} dateWhen={date}/>
                        <DateTimePickerInput type={'hour'} save={setHour} hourWhen={hour}/>

                        {
                            id &&
                            <View style={styles.inLine}>
                                <View style={styles.inputInLine}>
                                    <Switch onValueChange={() => setDone(!done)} value={done}
                                            thumbColor={done ? '#EE6B26' : '#20295F'}/>
                                    <Text style={styles.switchLabel}>Concluído</Text>
                                </View>
                                <TouchableOpacity>
                                    <Text style={styles.removeLabel}>Excluir</Text>
                                </TouchableOpacity>
                            </View>
                        }
                    </ScrollView>
            }
            <Footer icon={'save'} onPress={SaveTask}/>
        </KeyboardAvoidingView>
    )
}

Android 的 DateTimePickerInput 组件索引:

import React, {useEffect, useState} from "react";
import {TouchableOpacity, Image, TextInput, Platform, View, Alert} from "react-native";
import styles from "./styles";
import iconCalendar from '../../assets/calendar.png'
import iconClock from '../../assets/clock.png'
import {format, isPast} from "date-fns";
import RNDateTimePicker from "@react-native-community/datetimepicker";

export default function DateTimeInputAndroid({type, save, dateWhen, hourWhen}) {
    const [dateNow, setDateNow] = useState(new Date());
    const [mode, setMode] = useState('date');
    const [show, setShow] = useState(false);
    const [dateinput, setDateInput] = useState();
    const [timeinput, setTimeInput] = useState();

    const onChange = (event, selectedDate) => {
        const currentDate = selectedDate || dateNow;
        setShow(Platform.OS === 'ios');
        setDateNow(currentDate);
        if (event.nativeEvent.timestamp !== undefined) {
            if (!event.nativeEvent.timestamp.toString().includes('T')) {
                if (isPast(currentDate)) {
                    Alert.alert('Você não pode escolher uma data no passado!');
                } else {
                    setDateInput(format(currentDate, 'dd/MM/yyyy'));
                    save(format(currentDate, 'yyyy-MM-dd'));
                }
            } else {
                setTimeInput(format(currentDate, 'HH:mm'))
                save(format(currentDate, 'HH:mm:ss'));
            }
        }

    };

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

    const showDatepicker = () => {
        showMode('date');
    };

    const showTimepicker = () => {
        showMode('time');
    };

    // useEffect(() => {
    //     if (dateWhen) {
    //         setDateInput(format(new Date(dateWhen), 'dd/MM/yyyy'));
    //         // save(format(new Date(dateWhen), 'yyyy-MM-dd'));
    //     }
    //     if (hourWhen) {
    //         setTimeInput(format(new Date(hourWhen), 'HH:mm'));
    //         // save(format(new Date(hourWhen), 'HH:mm:ss'));
    //     }
    // });

    return (
        <View>
            <TouchableOpacity onPress={type === 'date' ? showDatepicker : showTimepicker}>
                <TextInput style={styles.input}
                           placeholder={type === 'date' ? 'Clique aqui para definir a data...' : 'Clique aqui para definir a hora...'}
                           editable={false}
                           value={type === 'date' ? dateinput : timeinput}

                />
                <Image style={styles.iconTextInput} source={type === 'date' ? iconCalendar : iconClock}/>
            </TouchableOpacity>
            {
                show && (
                    <RNDateTimePicker
                        value={dateNow}
                        mode={mode}
                        is24Hour={true}
                        display="default"
                        onChange={onChange}
                    />
                )
            }
        </View>
    )
};

注意:为了更好地可视化项目,只需访问以下链接:todo-mobile

【问题讨论】:

    标签: javascript node.js react-native expo datetimepicker


    【解决方案1】:

    感谢大家尝试回答并提供帮助。我能够找出哪里出了问题,并且该组件开始为任务的更新操作工作。

    在 Android 组件的 useEffect 中,我传递了一个空数组,这样应用程序只有在值发生变化时才会发生变化:

    import React, {useEffect, useState} from "react";
    import {TouchableOpacity, Image, TextInput, Platform, View, Alert} from "react-native";
    import styles from "./styles";
    import iconCalendar from '../../assets/calendar.png'
    import iconClock from '../../assets/clock.png'
    import {format, isPast} from "date-fns";
    import RNDateTimePicker from "@react-native-community/datetimepicker";
    
    export default function DateTimeInputAndroid({type, save, dateWhen, hourWhen}) {
        const [dateNow, setDateNow] = useState(new Date());
        const [mode, setMode] = useState('date');
        const [show, setShow] = useState(false);
        const [dateinput, setDateInput] = useState();
        const [timeinput, setTimeInput] = useState();
    
        const onChange = (event, selectedDate) => {
            const currentDate = selectedDate || dateNow;
            setShow(Platform.OS === 'ios');
            setDateNow(currentDate);
            if (event.nativeEvent.timestamp !== undefined) {
                if (!event.nativeEvent.timestamp.toString().includes('T')) {
                    //TODO: correct to allow selection of current date
                    if (isPast(currentDate)) {
                        Alert.alert('Você não pode escolher uma data no passado!');
                    } else {
                        setDateInput(format(currentDate, 'dd/MM/yyyy'));
                        save(format(currentDate, 'yyyy-MM-dd'));
                    }
                } else {
                    setTimeInput(format(currentDate, 'HH:mm'))
                    save(format(currentDate, 'HH:mm:ss'));
                }
            }
    
        };
    
        const showMode = (currentMode) => {
            setShow(true);
            setMode(currentMode);
        };
    
        const showDatepicker = () => {
            showMode('date');
        };
    
        const showTimepicker = () => {
            showMode('time');
        };
    
        useEffect(() => {
            if (dateWhen) {
                setDateInput(format(new Date(dateWhen), 'dd/MM/yyyy'));
                save(format(new Date(dateWhen), 'yyyy-MM-dd'));
            }
            if (hourWhen) {
                setTimeInput(format(new Date(hourWhen), 'HH:mm'));
                save(format(new Date(hourWhen), 'HH:mm:ss'));
            }
        }, []);
    
        return (
            <View>
                <TouchableOpacity onPress={type === 'date' ? showDatepicker : showTimepicker}>
                    <TextInput style={styles.input}
                               placeholder={type === 'date' ? 'Clique aqui para definir a data...' : 'Clique aqui para definir a hora...'}
                               editable={false}
                               value={type === 'date' ? dateinput : timeinput}
    
                    />
                    <Image style={styles.iconTextInput} source={type === 'date' ? iconCalendar : iconClock}/>
                </TouchableOpacity>
                {
                    show && (
                        <RNDateTimePicker
                            value={dateNow}
                            mode={mode}
                            is24Hour={true}
                            display="default"
                            onChange={onChange}
                            minimumDate={new Date()}
                        />
                    )
                }
            </View>
        )
    };
    

    【讨论】:

      猜你喜欢
      • 2021-03-16
      • 2016-04-27
      • 1970-01-01
      • 2018-09-15
      • 2019-11-08
      • 2015-05-17
      • 1970-01-01
      • 2011-07-02
      • 1970-01-01
      相关资源
      最近更新 更多