在子组件中使用TextInput创建登录表单

时间:2017-09-05 05:34:44

标签: react-native

我是React Native的新手,我正在尝试实现一个简单的登录表单。

我首先尝试了以下方法,其中有效:

import React, { Component } from 'react';
import {
  View,
  Text,
  TextInput,
  StyleSheet,
} from 'react-native';

import TitledInput from './login-form';

export default class LoginForm extends Component {
  constructor(props) {
      super(props);
      this.state = { email: '', password: ''};
  }

  render() {
    return (
      <View style={styles.container}>
        <TextInput
          label='Email Adress'
          placeholder='you@domain.com'
          value={this.state.email}
          onChangeText={(email) => this.setState({email})}
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
});

然后我想在另一个名为TitledInput的独立组件中拆分输入并尝试这个(它不起作用):

LoginForm的

    import React, { Component } from 'react';
    import {
      View,
      Text,
      StyleSheet,
    } from 'react-native';

    import TitledInput from './login-form';

    export default class LoginForm extends Component {
      constructor(props) {
          super(props);
          this.state = { email: '', password: ''};
      }

      render() {
        return (
          <View style={styles.container}>
            <TitledInput
              label='Email Adress'
              placeholder='you@domain.com'
              value={this.state.email}
              onChangeText={(email) => this.setState({email})}
            />
          </View>
        );
      }
    }

TitledInput

import React, { Component } from 'react';
import { View, Text, TextInput, StyleSheet } from 'react-native';

export default class TitledInput extends Component {
  const { inputStyle, labelStyle, containerStyle } = styles;

  render() {
    return (
      <View style={container}>
        <Text style={label}>{props.label.toUpperCase()}</Text>
        <TextInput
          autoCorrect={false}
          placeholder={props.placeholder}
          secureTextEntry={props.secureTextEntry}
          value={props.value}
          onChangeText={props.onChangeText}
          style={input}
        />
      </View>
    );
  }
}

我收到'maximum call stack exceeded'错误。

我可以在互联网上看到在setState函数中调用re-render时可能会发生此错误...但我不知道如何处理这种情况,我想要我的登录表单知道其输入子组件的值。

我想知道它,因为我会在点击提交按钮时使用它,还是状态的全部目的?

1 个答案:

答案 0 :(得分:0)

当您更改TiledInput中的电子邮件输入值时,电子邮件值将传播到LoginForm。在LoginForm中,由于状态“email”更改,登录表单将重新呈现。在这种情况下,您必须使用ComponentWillReceiveProps才能获取新的电子邮件值。

您可以在TitledInput中使用另一个状态值来保留电子邮件值,而不是这种方法。

import React, { Component } from 'react';
import {
  View,
  Text,
  StyleSheet,
} from 'react-native';

import TitledInput from './login-form';

export default class LoginForm extends Component {
  constructor(props) {
      super(props);
      this.state = { email: '', password: ''};
  }

  render() {
    return (
      <View style={styles.container}>
        <TitledInput
          label='Email Adress'
          placeholder='you@domain.com'
          onChangeText={(email) => this.setState({email})}
        />
      </View>
    );
  }
}

// TitledInput
import React, { Component } from 'react';
import { View, Text, TextInput, StyleSheet } from 'react-native';

export default class TitledInput extends Component {
    constructor(props) {
      super(props);
      this.state = { text: ''};
    }
  const { inputStyle, labelStyle, containerStyle } = styles;

  handleTextChange(value){
     this.setState({text:value});
     this.props.onChangeText(value);
  }
  render() {
        return (
          <View style={container}>
                <Text style={label}>{props.label.toUpperCase()}</Text>
                <TextInput
                  autoCorrect={false}
                  placeholder={props.placeholder}
                  secureTextEntry={props.secureTextEntry}
                  value={this.state.text}
                  onChangeText={this.handleTextChange()}
                  style={input}
                />
          </View>
        );
      }
    }

[update]通过使用onBlur而不是onChangeText,可以减少函数调用次数