Javascript 使用TextInput对本机Expo问题作出反应

Javascript 使用TextInput对本机Expo问题作出反应,javascript,react-native,redux,expo,Javascript,React Native,Redux,Expo,我正在使用React-Native、Redux、React-Navigation和Expo创建一个简单的事件跟踪程序,但在一个相当琐碎的部分上遇到了一些问题 我有一个窗体屏幕,您可以在其中输入事件名称、日期和其他信息。我正在使用输入事件的名称,但它不会输入onChange事件,只输入onChangeText。此外,当我使用onChange事件时,导航上的后退按钮将无响应,无论我在何处单击,光标仅保留在文本输入中 我遇到了另一个与内存有关的问题,这会导致模拟器在每次后续构建后加载的时间越来越长,并

我正在使用React-Native、Redux、React-Navigation和Expo创建一个简单的事件跟踪程序,但在一个相当琐碎的部分上遇到了一些问题

我有一个窗体屏幕,您可以在其中输入事件名称、日期和其他信息。我正在使用
输入事件的名称,但它不会输入
onChange
事件,只输入
onChangeText
。此外,当我使用
onChange
事件时,导航上的后退按钮将无响应,无论我在何处单击,光标仅保留在文本输入中

我遇到了另一个与内存有关的问题,这会导致模拟器在每次后续构建后加载的时间越来越长,并且在加载几次后变得无响应。我的手机expo应用程序偶尔也会崩溃。我有一种模糊的感觉,这两个问题是相关的,但我完全不知道这是什么问题。基本上,每次我保存文件时,Exponent模拟器的内存使用量都会翻倍

下面是
CreateEventScreen.js
目前的样子,我将在解决onChange问题后立即将其转换为Redux

export default class CreateEvent extends Component {
  constructor(){
    super();
    this.state = {
      name: '',
      date: new Date(),
      repeatAnnually: false,
      showDatePicker: false,
      wallPaperSource: null
    };
    this.toggleSelectWallPaper = this._toggleSelectWallPaper.bind(this);
    this.handleChange=this._handleChange.bind(this);
  }

  static navigationOptions = {
    title: 'Create New Event'
  }

  _handleToggleSwitch = () => this.setState(state => ({
    repeatAnnually: !this.state.repeatAnnually
  }));

  /* THIS IS NOT WORKING */
  _handleChange = (event) => {
    console.log(event);
    const target = event.target;
    const value = target.value;
    const name = target.name;
    this.setState({
      [name]: value
    })
  }

  _onDateChange = (date) => this.setState(state => ({
    date: date
  }));

  _toggleSelectWallPaper = async() => {
    let result;
    try {
      result = await ImagePicker.launchImageLibraryAsync({
        allowEditing: true,
        aspect: [4, 3]
      });
    } catch (e) {
        result = null;
    }

    if(!result.cancelled){
      this.setState({
        wallPaperSource: result.uri
      });
    }

  }

  _renderDatePicker(){
    if(this.props.showDatePicker){
      return (
          <DatePickerIOS
            date={this.state.date}
            mode="date"
            onDateChange={this._onDateChange}
          />
      )
    } else {
      return null;
    }
  }

  render(){
    const { onClick, toggleDatePicker, showDatePicker } = this.props
    let { wallPaperSource } = this.state;
    return(
      <View>
        <TextInput
          style={styles.input}
          name="name"
          placeholder="Event Name"
          value={this.state.name}
          /* THIS IS NOT WORKING */
          onChange={this._handleChange}
          /* This works but not ideal for redux integration */
          // onChange={(event) => this.setState({'name': event.target.value})}  
        />
        <View style={styles.eventDetailsContainer}>
          <View style={styles.itemContainer}>
            <Text>Repeat Annually</Text>
            <Switch
              onValueChange={this._handleToggleSwitch}
              value={this.state.repeatAnnually}
            />
          </View>
          <TouchableOpacity onPress={e => {
            e.preventDefault()
            toggleDatePicker(showDatePicker)
          }}>
            <View style={styles.itemContainer}>
              <Text>Select Date</Text>
              <Text>{this.state.date.toLocaleDateString()}</Text>
            </View>
          </TouchableOpacity>
          <View>
            {this._renderDatePicker()}
          </View>
        </View>
        <View style={styles.eventDetailsContainer}>
          <TouchableOpacity onPress={this.toggleSelectWallPaper}>
            <View style={styles.itemContainer}>
              <Text>Wallpaper</Text>
              { this.state.wallPaperSource  ?
                <Image source={{ uri: wallPaperSource }} style={{ width: 100, height: 100 }}/>
                 : null
              }
            </View>
          </TouchableOpacity>
        </View>
        <Button
          style={styles.submitBtn}
          onPress={e => {
            e.preventDefault()
            if(!this.state.name.trim()){
              return
            }
            onClick(this.state)
          }}
          color="#1e90ff"
          title="Create Event"
        />
    </View>
    )
  }
}

任何帮助或反馈都将不胜感激。谢谢

提供给
onChange
的事件对象很大,如果记录,将停止其他js执行。只需删除
console.log(事件)

使用
onChange
时,可以使用
event.nativeEvent.text
检索输入值。不过,这不是捕获输入值的方式。正确的方法是使用
onChangeText

TextInput
没有名为name的属性,该属性将被忽略

// This will not be defined
const name = target.name;
您可以向
\u handleChange
提供其他参数以完成预期操作:

onChangeText={(value) => this._handleChange(value, 'keyName')}

如果要自动处理此问题(例如,对于大量输入),请参阅。

是否有不希望使用
onChangeText
的原因?只是一个猜测,但事件对象可能很大,简单地记录它可能会停止其他js执行。如果您删除
console.log
,这是否解决了无响应问题?我不使用
OnChangeText
的原因是它的可重用性不强,因为我必须手动设置正在更新的密钥。此外,我认为当我在这个组件中实现redux时,它会变得更加复杂。您删除
控制台.log的操作是正确的!谢谢你。
onChange
事件起作用。但是现在我正在记录target
console.log('target',event.target)
,它给我的所有输入都是“47”。好的。这也可以通过向
onChangeText
提供附加参数来解决:
onChangeText={(value)=>this.\u handleChange(value,'keyName')}
。redux集成不应该改变这种逻辑,只会使信息流链变长。是的,我想我可以用
onChangeText
来做,但我更喜欢动态地做,而不是传递静态值。谢谢你的帮助。
onChangeText={(value) => this._handleChange(value, 'keyName')}