在空的输入字段ReactJS上显示错误

时间:2019-04-13 15:54:26

标签: javascript reactjs

我试图基于两个文本输入字段中是否都存在任何字符来启用/禁用表单按钮,但是由于某种原因,尽管我记录了状态,但状态长度却使我的条件错误它出现了。

错误:

const isEnabled = this.state.subject.length > 0 && this.state.emails.length > 0; 
//Uncaught TypeError: Cannot read property 'length' of undefined

完整代码:

import React from 'react';

export default class EmailAnnotationForm extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            csrf: '',
            subject: '',
            emails: '',
            comment: ''
        }
        this.handleInputChange = this.handleInputChange.bind(this);
        this.handleFormSubmit = this.handleFormSubmit.bind(this);
        this.handleClearForm = this.handleClearForm.bind(this);
        this.input = React.createRef();
    }

    componentDidMount() {
        console.log(this.state.subject.length) // renders correct value => 0
        this.setState({subject: this.props.title });
    }

    handleInputChange(event) {
        const target = event.target;
        const value = target.type === 'checkbox' ? target.checked : target.value;
        const name = target.name;
        this.setState({
            [name]: value
        });
    }

    handleClearForm() {
        this.setState({
            csrf: '',
            subject: '',
            emails: '',
            comment: ''
        })
    }

    handleFormSubmit(event) {
        var emailSubject;  
        {
            this.state.subject ? emailSubject = this.state.subject : emailSubject = this.props.title
        }; //

        const body = {
            subject: emailSubject,
            emails: this.state.emails,
            comment: this.state.comment
        };

        event.preventDefault();
        var route = `${API_ROOT}` + '/api/annotation/' + this.props.annotationId + '/share/email';
        fetch(route,
            {
                method: 'POST', 
                body: JSON.stringify(body),
                compress: false,
                headers: { 
                    'X-CSRF-Token': this.props.csrf,
                    'Accept': 'application/json',
                    'Content-Type': 'application/json'
                }
            })
            .then(res => {
                return res.json();
            })  
            .then(data => {
                this.handleClearForm();
                this.props.shareFlashMessage('success');
                this.setState({'flash': 'success'});
                this.props.closeShareModal(false);
            }) 
            .catch(err => {
                console.log(err);
                this.props.shareFlashMessage('error');
                this.setState({'flash': 'error'});
            });
    }


    render() {
        var emailSubject;  
        {
            this.state.subject 
                ? 
            emailSubject = this.state.subject 
                : 
            emailSubject = this.props.title
        };

        console.log(this.state) // csrf: '', subject: undefined, emails: '', comment: ''
        console.log(this.state.subject) // renders undefined

        const isEnabled = this.state.subject.length > 0 && this.state.emails.length > 0; //Uncaught TypeError: Cannot read property 'length' of undefined

        return (
            <div className="annotation-footer__share-form-email">
                <form action={"/api/annotation/" + this.props.annotationId + "/share/email"} method="post" onSubmit={this.handleFormSubmit} name="annotationEmailShare" id="share-email-form">
                    <div className="input-group annotation-footer__share-form-email-inputs">
                        <p><b>Subject:</b></p>
                        <input type="text" name="subject" className="form-control" defaultValue={this.props.title} onChange={this.handleInputChange}/><br />
                    </div>
                    <div className="input-group annotation-footer__share-form-email-inputs">
                        <p><b>Emails (Comma separate each email address):</b></p>
                        <input type="text" name="emails" className="form-control" onChange={this.handleInputChange}/><br />
                    </div>
                    <div className="input-group annotation-footer__share-form-email-inputs">
                        <p><b>Additional Comment (Optional):</b></p>
                        <textarea name="comment" rows="4" className="form-control" onChange={this.handleInputChange}></textarea><br />
                    </div>
                    <button type="submit" disabled={!isEnabled}>Send Email</button>
                </form>
            </div>
        )
    }
}

1 个答案:

答案 0 :(得分:1)

似乎this.props.title未定义。

要解决此问题,请选中this.props.title值,并仅在其值有效时更新状态。像这样:

componentDidMount() {
  if(this.props.title)
    this.setState({ subject: this.props.title });
}

建议:

而不是使用subject方法中的props值更新didMount,而是在构造函数本身中完成,就像这样:

this.state = {
  csrf: '',
  subject: props.title || '',
  emails: '',
  comment: ''
}