带有验证的ReactJS TextInput组件 - OnChange无法正常工作

时间:2017-02-14 15:09:46

标签: reactjs ecmascript-6 textinput

我创建了一个TextInput组件,它既可以作为文本框,也可以作为textarea和验证 当我使用handleChange事件创建一个TextInput标记时,它不会触发。

<TextInput
                  ref="c1"
                  className="form-control"
                  type="textarea"
                  rows={4}
                  required
                  errorMessage="c1is invalid"
                  emptyMessage="c1is required"
                  handleChange={this.handleSuggestedReplyChange}
                  value={this.state.answeredBy || ''}
                />

handleSuggestedReplyChange是一个写在模板页面中的事件。

&#13;
&#13;
import React from 'react';
import composeValidationComponent from './ValidationComponent';

class TextInput extends React.Component {
    constructor(props, context) {
        super(props, context);
        this.displayName = 'TextInput';
    }

    render() {
        if (this.props.type === 'textarea') {
            return (
            <textarea
              className={this.props.className}
              rows={this.props.rows}
              onChange={this.props.handleChange}
              value={this.props.value}
              readOnly={this.props.readOnly}
            />
            );
        }
        return (
            <input
              type={this.props.type}
              placeholder={this.props.placeholder}
              className={this.props.className}
              onChange={this.props.handleChange}
              value={this.props.value}
              readOnly={this.props.readOnly}
            />
        );
    }
}

TextInput.propTypes = {
    type: React.PropTypes.string,
    placeholder: React.PropTypes.string,
    className: React.PropTypes.string,
    value: React.PropTypes.string,
    rows: React.PropTypes.number,
    readOnly: React.PropTypes.bool,
    handleChange: React.PropTypes.func,
};

export default composeValidationComponent(TextInput, 'TextInput');
&#13;
&#13;
&#13;

&#13;
&#13;
import React from 'react';
import InputError from './InputError';

export default function composeValidationComponent(Component, DisplayName) {
    class ValidationComponent extends React.Component {
        constructor(props, context) {
            super(props, context);

            this.state = {
                isEmpty: true,
                //value: '',
                valid: false,
                errorMessage: '',
                errorVisible: false
            };

            this.handleChange = this.handleChange.bind(this);
            this.validation = this.validation.bind(this);
        }

        handleChange(event) {
            // set the state in order for it to show up on the form
            this.setState({
                value: event.target.value
            });
        }

        validation(value, valid) {
            let isValid = valid;
            //The valid variable is optional, and true if not passed in:
            if (typeof valid === 'undefined') {
                isValid = true;
            }

            let message = '';
            let errorVisible = false;

            //we know how to validate text fields based on information passed through props
            if (!isValid) {
                // NOTE: This should never be reached since we don't handle onBlur
                //This happens when the user leaves the field, but it is not valid
                //(we do final validation in the parent component, then pass the result
                //here for display)
                message = this.props.errorMessage;
                errorVisible = true;
            } else if (this.props.required && value.length === 0) {
                //this happens when we have a required field with no text entered
                //in this case, we want the "emptyMessage" error message
                message = this.props.emptyMessage;
                isValid = false;
                errorVisible = true;
            }

            //setting the state will update the display,
            //causing the error message to display if there is one.
            this.setState({
                value,
                isEmpty: message === this.props.emptyMessage,
                isValid,
                errorMessage: message,
                errorVisible
            });

            return isValid;
        }

        render() {
            return (
                <div>
                    <Component
                      { ...this.props }
                      { ...this.state }
                      handleChange={ this.handleChange }
                      validation={ this.validation }
                    />
                    <InputError
                      visible={this.state.errorVisible}
                      errorMessage={this.state.errorMessage}
                    />
                </div>
            );
        }
    }

    ValidationComponent.propTypes = {
        className: React.PropTypes.string,
        name: React.PropTypes.string,
        errorMessage: React.PropTypes.string,
        emptyMessage: React.PropTypes.string,
        required: React.PropTypes.bool,
        readOnly: React.PropTypes.bool
    };

    return ValidationComponent;
}
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:2)

我想我看到了这个问题。我假设您期待this.handleSuggestedReplyChange被调用,但事实并非如此。

这是因为验证类包装器。在render方法中,您将所有props和state传递给组件,然后指定自定义handleChange。你提供的那个道具将覆盖通过this.props传递的那个。

要解决此问题,我建议您在ValidationComponent的handleChange中调用this.props.handleChange()

&#13;
&#13;
handleChange(event) {
    // set the state in order for it to show up on the form
    this.setState({
        value: event.target.value
    });
    if (this.props.handleChange) {
      this.props.handleChange(event.target.value);
    }
}
&#13;
&#13;
&#13;