【问题标题】:Avoid showing error messages while getting the value from TForm.getValue()从 TForm.getValue() 获取值时避免显示错误消息
【发布时间】:2018-03-12 14:41:18
【问题描述】:

我有 2 个文本框

  • 电子邮件
  • 密码

我想禁用该按钮,直到用户输入有效的电子邮件和密码。因此,在 onChange 方法中,我从form.getValue() 检索值,该值触发文档中所述的验证。如果值为null,我将按钮的禁用状态更改为true,否则为false。我只想在输入失去焦点或提交时显示错误,而不是在每个 getValue() 调用时显示错误。

只要onChange 被触发,表单就会开始在所有字段中显示错误,因为我调用了form.getValue()。我只想在用户移动到下一个文本框(焦点从当前文本框丢失)或用户点击提交时才显示错误。当用户刚开始在文本框中输入时,我不想用错误消息来纠缠他。

复制步骤

  • 使用 包含错误消息的选项
  • 在 onChange 方法中检索值
  • 您将开始看到错误消息。

代码

// @flow
import React, { PureComponent } from 'react';
import { View, Text, Platform, TouchableHighlight } from 'react-native';
import t from 'tcomb-form-native';
import { resetTo } from 'src/lib/navigation';
import { SIGNED_IN } from 'src/routes/constants';
import { getErrorMessage } from 'src/lib/auth-helpers';
import { FullScreenBGImage } from 'src/components';
import { text, background } from 'src/styles/';
import LoginBG from '../../../assets/images/login-bg.jpg';
import styles from './style';

type Props = {
  loggedIn: boolean,
  navigation: Object,
  login: (string, string) => void,
  user: Object,
};

type States = {
  isDisabled: boolean,
  value: ?Object,
};

const Email = t.refinement(t.String, email => {
  const reg = /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/;
  return reg.test(email);
});

const { Form } = t.form;

// here we define our domain model
const LoginForm = t.struct({
  email: Email,
  password: t.String,
});

const textboxStyle = {
  color: text.color2,
  backgroundColor: background.color1,
  fontSize: 17,
  height: 50,
  paddingVertical: Platform.OS === 'ios' ? 7 : 0,
  paddingHorizontal: 16,
  borderWidth: 1,
  marginBottom: 5,
};

const formStylesheet = {
  ...Form.stylesheet,
  textbox: {
    normal: {
      ...textboxStyle,
    },
    error: {
      ...textboxStyle,
    },
  },
  errorBlock: {
    color: text.error,
  },
};

const formOptions = {
  auto: 'placeholders',
  fields: {
   email: { error: 'Enter valid email' },
    password: {
      error: 'Enter valid password'
      password: true,
      secureTextEntry: true,
    },
  },
  stylesheet: formStylesheet,
};

class Login extends PureComponent<Props, States> {
  loginForm: ?Object;
  onFormChange: () => void;

  static navigationOptions = {
    header: null,
  };

  constructor(props: Props) {
    super(props);

    this.loginForm = {};

    this.state = {
      value: null,
      isDisabled: true,
    };

    this.handleSubmit = this.handleSubmit.bind(this);
    this.onFormChange = this.onFormChange.bind(this);
  }

  /**
   * ComponentWillReceiveProps.
   *
   * Redirect if user is logged in
   */
  componentWillReceiveProps(nextProps: Props) {
    if (nextProps.loggedIn !== this.props.loggedIn && nextProps.loggedIn) {
      resetTo(SIGNED_IN, nextProps.navigation);
    }
  }

  handleSubmit = () => {
    // use that ref to get the form value
    const value = this.loginForm ? this.loginForm.getValue() : null;

    if (value) {
      this.props.login(value.email, value.password);
    }
  }

  onFormChange() {
    const value = this.loginForm ? this.loginForm.getValue() : null;

    if (value) {
      this.setState({
        value,
        isDisabled: false,
      });
    }
  }

  render() {
    const errorMessage = getErrorMessage(this.props.user);
    const error = errorMessage
      ? <View><Text style={styles.errorMessage}>{errorMessage}</Text></View>
      : null;

    return (
      <View style={styles.container}>
        <FullScreenBGImage imageSrc={LoginBG} styles={styles.bgImage}>
          <View style={styles.logo}>
            <Text style={styles.logoLabel}>VERUS</Text>
          </View>

          <View style={styles.loginForm}>
            {error}
            <Form
              ref={c => { this.loginForm = c; }}
              type={LoginForm}
              value={this.state.value}
              onChange={this.onFormChange}
              options={formOptions} // pass the options via props
            />

            <TouchableHighlight
              style={styles.button}
              onPress={this.handleSubmit}
              underlayColor="#99d9f4"
              disabled={this.state.isDisabled}
            >
              <Text style={styles.buttonText}>Sign In</Text>
            </TouchableHighlight>
          </View>
        </FullScreenBGImage>
      </View>
    );
  }
}

export default Login;

版本

tcomb-form-native v0.6.11

【问题讨论】:

  • 我认为您应该将const errorMessage = getErrorMessage(this.props.user); 放入handleSubmit 函数并设置用于渲染的错误状态。
  • @TuấnTrầnDuy 与表格完全无关。 errorMessage 是根据从服务器检索到的错误生成的。
  • 是的,但是当你改变表单并且errorMessage不是null时它总是重新渲染,所以我只是建议你把它移到其他函数比如onSubmit并将它设置为顺便说一句。

标签: javascript reactjs react-native tcomb-form-native


【解决方案1】:

嘿,通过该方法将始终首先验证表单,因此您只需更改 onChange 的方法并使用 this.refs.loginForm.refs.input.refs.email.state.value 之类的方式获取所需电子邮件字段的值,其中电子邮件是您的字段名称和 loginForm您的表单引用的名称。然后您可以自己使用正则表达式测试该值以更改按钮的状态;)

一些给我这个想法的文档: 这里:https://github.com/gcanti/tcomb-form/issues/370

这里是https://github.com/gcanti/tcomb-form/blob/master/GUIDE.md#accessing-fields

【讨论】:

  • 我已经知道这种方法了。但是,我想也许有更好的方法。无论如何,谢谢。
  • 没问题 ;) 如果有另一个我也很想听 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多