React的setState仅选择性地更新状态

时间:2018-12-03 08:27:54

标签: reactjs react-native

我正在根据其文档使用react-native-modal-datetime-picker。我正在尝试将日期(显示在handleStartDatePicked函数内的控制台日志中)保存为this.state.startDateTime。我试图通过使用React的setState来做到这一点,但是它不起作用。出于好奇,我尝试更改另一个属性(在下面的示例中为“ startDateTimeNew”),并且此属性正在正确更新。我不知道为什么目标变量“ startDateTime”不会更新。

import React, { Component } from 'react';
import { connect } from 'react-redux';
import {
  Text,
  View,
  StyleSheet,
  TextInput,
  TouchableOpacity,
} from 'react-native';
import DateTimePicker from 'react-native-modal-datetime-picker';
import moment from 'moment';

class SessionScreen extends Component {
  static navigationOptions = {
    title: 'View Session',
  };

  state = {
    details: '',
    endDateTime: '',
    endDateTimePickerVisible: false,
    startDateTime: '',
    startDateTimePickerVisible: false,
  };

  handleEndDatePicked = (date) => {
    console.log('A date has been picked: ', date);
    this.hideEndDateTimePicker();
  };

  handleInputChangeFor = (propertyName,text) => {
    this.setState({
        ...this.state,
        [propertyName]: text,
    });
    console.log('this.state:',this.state);
  }

  handleStartDatePicked = (date) => {
    console.log('A date has been picked: ', date, 'formatted:', moment(date).format('dddd[,] MMM Do h:mm A'));
    this.setState({
        ...this.state,
        startDateTimeNew: date.toString(),
        startDateTime: date.toString(),
    }, function() {
        console.log('new state',this.state);
    });
    console.log('this.state:', this.state);
    this.hideStartDateTimePicker();
  };

  hideEndDateTimePicker = () => this.setState({ ...this.state, endDateTimePickerVisible: false });

  hideStartDateTimePicker = () => this.setState({ ...this.state, startDateTimePickerVisible: false });

  showEndDateTimePicker = () => this.setState({ ...this.state, endDateTimePickerVisible: true });

  showStartDateTimePicker = () => this.setState({ ...this.state, startDateTimePickerVisible: true });

  render() {
    const {navigate} = this.props.navigation;

    return (
      <View style={styles.container}>
        <Text style={styles.header}>START TIME</Text>
        <TouchableOpacity onPress={this.showStartDateTimePicker} style={styles.touchableOpacity}>
          {/* <Text style={styles.touchableOpacityText}><this.dateTimeStart /></Text> */}
          <Text style={styles.touchableOpacityText}>Click to set start day and time</Text>
        </TouchableOpacity>
        <Text style={styles.header}>END TIME</Text>
        <TextInput 
            style={styles.input}
            placeholder="Click to add end day and time..."
            returnKeyType="go"
            autoCapitalize="none"
            autoCorrect={false}
            onChangeText={(input) => this.handleInputChangeFor('end',input)}
        />
        <Text style={styles.header}>DETAILS</Text>
        <TextInput 
            style={styles.input}
            placeholder="Enter details about this chill..."
            returnKeyType="go"
            autoCapitalize="none"
            autoCorrect={false}
            onChangeText={(input) => this.handleInputChangeFor('details',input)}
        />
        <DateTimePicker
          isVisible={this.state.startDateTimePickerVisible}
          onConfirm={this.handleStartDatePicked}
          onCancel={this.hideStartDateTimePicker}
          mode={'datetime'}
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#b2f6ff',
    padding: 10
  },
  header: {
    fontSize: 14,
    marginBottom: 8,
    color: 'black',
    opacity: 0.8,
  },
  input: {
    height: 40,
    backgroundColor: 'white',
    marginBottom: 10,
    paddingHorizontal: 10,
    width: 'auto'
  },
  touchableOpacity: {
    height: 40,
    backgroundColor: 'white',
    marginBottom: 10,
    paddingHorizontal: 10,
    width: 'auto',
    justifyContent: 'center',
  },
  touchableOpacityText: {
    opacity: 0.5
  }
})

const mapReduxStateToProps = reduxState => (
  {reduxState}
);

export default connect(mapReduxStateToProps)(SessionScreen);

我尝试同时使用date.toString()和moment(date).format('dddd [,] MMM Do h:mm A'设置startDateTime。输入到该函数的日期是一个对象,但成功变成带有正确数据的字符串。

1 个答案:

答案 0 :(得分:0)

我仍然不确定为什么setState不起作用,因为它是从我的问题的代码中写入的(特别是因为该设置在文件中的其他地方起作用),但是我已经能够通过设置状态找到解决方法可以通过以下方式:

let newState = this.state;
newState.startDateTime = date.toString();
this.setState(newState, function() {
    console.log('new state',this.state);
});

我仍然欢迎有人对我的问题中的代码为何不成功的任何解释。