首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法更新父组件的状态。重置表单失败

无法更新父组件的状态。重置表单失败
EN

Stack Overflow用户
提问于 2021-04-14 16:07:24
回答 2查看 25关注 0票数 0

function DateTimePick是一个子函数,用于在父组件保留中呈现领料日期和领料时间。目前代码有两个问题: 1。提交数据后,保留中的表单不会重置。2.子DateTimePick无法更新父保留中“date”和“time”的状态。请看一看,让我知道如何解决这些问题。谢谢。

子函数DateTimePick如下:

代码语言:javascript
复制
import React, {useState} from 'react';
import {View, Button, Platform, Text, TextInput, StyleSheet} from 'react-native';
import DateTimePicker from '@react-native-community/datetimepicker';
import { Icon } from 'react-native-elements';
import Moment from "moment";

export const DateTimePick = () => {  
  
  const [date, setDate] = useState(new Date());
  const [mode, setMode] = useState('date');
  const [show, setShow] = useState(false);
  
  const onChange = (event, selectedDate) => {
      const currentDate = selectedDate || date;
      setShow(Platform.OS === 'ios');
      setDate(currentDate);
  };
  
  const showMode = (currentMode) => {
      setShow(true);
      setMode(currentMode);
  };
  
  const showDatepicker = () => {
      showMode('date');
  };
  
  const showTimepicker = () => {
      showMode('time');
  };
    
      return (
      <View>                
          <View style={styles.formRow}>
              <Text style={styles.formLabel}> Date</Text>
              <Text onPress={showDatepicker} style={styles.formItem} value_date={date.toDateString()} onChange = {(value_date) => this.props.setState({date: value_date})}><Icon type='font-awesome-5' name='calendar' color='#512DA8' />{' ' + Moment(date).format('DD-MMM-YYYY') }</Text>
          </View>
          <View style={styles.formRow}>
              <Text style={styles.formLabel}> Time</Text>
              <Text onPress={showTimepicker} style={styles.formItem} value_time={date.toTimeString()} onChange = {(value_time) => this.props.setState({time: value_time})}><Icon type='font-awesome-5' name='clock' color='#512DA8' /> {' ' + Moment(date).format('h:mm A') }</Text>
          </View>
          {show && (
          <DateTimePicker
              testID="dateTimePicker"
              value={date}
              mode={mode}
              is24Hour={true}
              display="default"
              onChange={onChange}
          />
          )}        
      </View>
      );
  };

//export default DateTimePick;

const styles = StyleSheet.create({
  formRow: {
      alignItems: 'center',
      justifyContent: 'center',
      flex: 1,
      flexDirection: 'row',
      margin: 20
  },
  formLabel: {
      fontSize: 18,
      flex: 1
  },
  formItem: {
      flex: 1        
  },
  modal: {
      justifyContent: 'center',
      margin: 20
  },
  modalTitle: {
      fontSize: 24,
      fontWeight: 'bold',
      backgroundColor: '#512DA8',
      textAlign: 'center',
      color: 'white',
      marginBottom: 20
  },
  modalText: {
      fontSize: 18,
      margin: 10
  },
})

parent Reservation,生成预约表单和预约输入确认模式

代码语言:javascript
复制
import React, {Component} from 'react';
import { Text, View, ScrollView, StyleSheet, Switch, Button, TextInput, Modal} from 'react-native';
import {DateTimePick} from './DateTimePickComponent';

class Reservation extends Component {
    constructor(props) {
        super(props);
        this.state = {
            guests: 1,
            smoking: false,
            notes:'',
            date: new Date().toDateString(),
            time: new Date().toTimeString(),
            showModal: false          
        }
    }

    toggleModal() {
        this.setState({showModal: !this.state.showModal})
    }

    handleReservation() {
        console.log(JSON.stringify(this.state));  //log current state
        //this.setState({                           // reset the form  
        //})
        this.toggleModal();
    }

    resetForm() {
        this.setState({
            guests: 1,
            smoking: false,
            notes:'',
            date: new Date().toDateString(),
            time: new Date().toTimeString(),
            showModal: false 
        });
    }

    
    render() {
            //, transform: [{ scaleX: 3 }, { scaleY: 1.5 }]   => for switch
        return(
            <ScrollView>
                <View style={styles.formRow}>
                    <Text style={styles.formLabel}> Guests </Text>
                    <TextInput style={styles.formItem} keyboardType="numeric" placeholder="Number" 
                        value_guests={this.state.guests}
                        onChangeText = {(value_guests) => this.setState({guests: value_guests})} >                                                   
                    </TextInput>
                </View>

                <View style={styles.formRow}>
                    <Text style={styles.formLabel}> Notes </Text>
                    <TextInput style={styles.formItem} keyboardType="default" placeholder="Allergy,..etc"  
                      value_notes={this.state.notes}
                      onChangeText = {(value_notes) => this.setState({notes: value_notes})} >                             
                    </TextInput>
                </View>                
                <View style={styles.formRow}>                     
                    <Text style={styles.formLabel}> Non-Smoking </Text>                   
                    <Switch style={{ flex: 1, backgroundColor: "orange", paddingLeft:0, marginLeft:0 }} trackColor={{true: 'red', false: 'grey'}}
                    value={this.state.smoking} 
                    onValueChange = {(value) => this.setState({smoking: value})} />
                    <Text style={styles.formLabel}> Smoking </Text>                    
                </View>
                                          
                <DateTimePick />

                <View style={styles.formRow}>
                    <Button
                        onPress={() => this.handleReservation()}
                        title="Reserve"
                        color="#512DA8"
                        accessibilityLabel="Learn more about this purple button"
                        />
                </View>

                <Modal animationType={'slide'} transparent={false} visible={this.state.showModal}
                onDismiss={() => {this.toggleModal()}}
                onRequestClose={() => {this.toggleModal()}}>
                    <View style={styles.modal}>
                        <Text style={styles.modalTitle}>Your Reservation</Text>
                        <Text style={styles.modalText}>Number of Guests: {this.state.guests}</Text>
                        <Text style={styles.modalText}>Notes: {this.state.notes}</Text>
                        <Text style = {styles.modalText}>Smoking?: {this.state.smoking ? 'Yes' : 'No'}</Text>
                        <Text style = {styles.modalText}>Date and Time: {this.state.date} {this.state.time}</Text>
                        <Button 
                            onPress = {() =>{this.toggleModal(); this.resetForm();}}
                            color="#512DA8"
                            title="Close" 
                            />
                    </View>

                </Modal>
            </ScrollView>
        );
    }
}

const styles = StyleSheet.create({
    formRow: {
        alignItems: 'center',
        justifyContent: 'center',
        flex: 1,
        flexDirection: 'row',
        margin: 20
    },
    formLabel: {
        fontSize: 18,
        flex: 1
    },
    formItem: {
        flex: 1        
    },
    modal: {
        justifyContent: 'center',
        margin: 20
    },
    modalTitle: {
        fontSize: 24,
        fontWeight: 'bold',
        backgroundColor: '#512DA8',
        textAlign: 'center',
        color: 'white',
        marginBottom: 20
    },
    modalText: {
        fontSize: 18,
        margin: 10
    },
})

export default Reservation;
EN

回答 2

Stack Overflow用户

发布于 2021-04-14 16:33:34

您可以通过将state consts date,show,mode转移到parent Reservation来修复它

然后将状态更改函数传递给props中的DateTimePick组件,如下所示

代码语言:javascript
复制
<DateTimePick onDateChange={(date) => this.setState({date: date}) } />

在DateTimePick组件中:

代码语言:javascript
复制
 const onChange = (event, selectedDate) => {
      const currentDate = selectedDate || date;
      setShow(Platform.OS === 'ios');
      props.onDateChange(currentDate);
  };

另外,别忘了在组件中传递道具,比如

代码语言:javascript
复制
export const DateTimePick = (props) => { 
票数 1
EN

Stack Overflow用户

发布于 2021-04-15 12:37:07

解决了它。有关使用子数据更新父代的状态需要传递将父代的状态设置为子代的处理程序的信息,请参阅How to update parent's state in React?

代码语言:javascript
复制
class Parent extends React.Component {
  constructor(props) {
    super(props)

    this.handler = this.handler.bind(this)
  }

  handler() {
    this.setState({
      someVar: 'some value'
    })
  }

  render() {
    return <Child handler = {this.handler} />
  }
}

class Child extends React.Component {
  render() {
    return <Button onClick = {this.props.handler}/ >
  }
}

在实现中,处理程序被插入到父类保留中,如下所示

代码语言:javascript
复制
...
class Reservation extends Component {
    constructor(props) {
...
this.handler = this.handler.bind(this) 
    }

    handler(selectedDate) {
        this.setState({
            date: Moment(selectedDate).format('DD-MMM-YYYY'),
            time: Moment(selectedDate).format('h:mm A'), 
        })
      }
...

在子DateTimePick中,将处理程序嵌入到onChange中,以便将子更新从onChange传递到父保留中的状态更新,如下所示

代码语言:javascript
复制
...

export const DateTimePick = (props) => {
    const handler = props.handler;
    ...

    const onChange = (event, selectedDate) => {
        ...
        handler(currentDate);
    };
...
...
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67087828

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档