TextInput

时间:2017-08-10 04:00:48

标签: javascript react-native redux expo

我正在使用React-Native,Redux,React-Navigation和Expo创建一个简单的事件跟踪器应用程序,而且我在一个相当微不足道的部分遇到了一些麻烦。

我有一个表单屏幕,您可以在其中输入事件名称,日期和其他信息。我使用<TextInput/>输入了该活动的名称,但它不会参加onChange活动,只有onChangeText。此外,当我使用onChange事件时,导航上的后退按钮变得无法响应,无论我点击哪里,光标都只保留在TextInput中

我有另一个与内存有关的问题导致模拟器在每次连续构建后加载的时间越来越长,并在几次加载后变得没有响应。我的移动世博应用程序偶尔会崩溃。我有点模糊的感觉,这两个问题是相关的,但我完全不知道问题是什么。基本上,每次保存文件时,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>
    )
  }
}

package.json -

{
  "name": "floss-evens",
  "version": "0.0.0",
  "description": "Hello Expo!",
  "author": null,
  "private": true,
  "main": "node_modules/expo/AppEntry.js",
  "dependencies": {
    "expo": "^18.0.4",
    "lodash": "^4.17.4",
    "moment": "^2.18.1",
    "prop-types": "^15.5.10",
    "react": "16.0.0-alpha.12",
    "react-native": "https://github.com/expo/react-native/archive/sdk-18.0.1.tar.gz",
    "react-native-image-picker": "^0.26.3",
    "react-navigation": "^1.0.0-beta.11",
    "react-redux": "^5.0.5",
    "redux": "^3.7.2"
  }
}

非常感谢任何帮助或反馈。谢谢!

1 个答案:

答案 0 :(得分:1)

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

使用onChange时,可以使用event.nativeEvent.text检索输入值。但是,这不是你应该如何捕获输入值。正确的方法是使用onChangeText

TextInput没有名为 name 的属性,只会被忽略。

// This will not be defined
const name = target.name;

您可以向_handleChange提供其他参数以完成预期的操作:

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

如果您想自动处理此问题,例如对于大量输入,请参阅this question