簡體   English   中英

js 中函數的上下文可見性(React.js)

[英]Context visiability for function in js (React.js)

你能解釋為什么反應狀態在函數handleFinishChange中可見而在validationFinishTime中看不到。 兩者都轉移到組件InputFieldForm 執行此代碼會導致Uncaught TypeError: Cannot read property 'finish' of undefined in validationFinishTime when the field is changed in input

組件ShiftFormAdmin

import React from 'react'
import {browserHistory} from 'react-router'
import Loading from './../form/loading.jsx'
import message from './../../constants/message';
import style from './../../constants/style';
import ErrorInformation from '../form/ErrorInformationForm.jsx';
import InputFieldForm from '../form/InputFieldForm.jsx';
import SelectFieldForm from '../form/SelectFieldForm.jsx';
import urls from './../../constants/urls'
import moment from 'moment';

export default class ShiftFormAdmin extends React.Component{

constructor(props){
    super(props)
    this.state = {
        box : {value : '', isValid : true},
        washerMan : {value : "", isValid : true},
        finish : {value : this.props.finish, isValid : true},
        start : '',
        availableWasherManList : [],
        boxCount : this.props.initData.boxCount,
        errorDisplay : style.DISPLAY_NONE,
        errorMessage : message.MESSAGE_DEFAULT_ERROR,
        isWasherMansDownloaded: false,
        isCurrentTimeDownloaded : false
    }
    this.handleSubmit = ::this.handleSubmit
    this.handleBoxChange = ::this.handleBoxChange
    this.downloadWasherMans = ::this.downloadWasherMans
    this.filterWasherMan = ::this.filterWasherMan
    this.downloadServerTime = ::this.downloadServerTime
    this.setStartTime = :: this.setStartTime
    this.handleFinishChange = ::this.handleFinishChange
}

handleFinishChange(e){
    this.setState({
        finish : {
            value : e.target.value,
            isValid : true
        }
    })
}

validationFinishTime(value){
    let result = false;
    console.log(this.state.finish.value)
    return result;
}

render(){
    let data = <Loading/>
    let boxCount = [];
    for(let i=1; i<=this.state.boxCount; i++){
        boxCount.push(i);
    }

    if(this.state.isWasherMansDownloaded && this.state.isCurrentTimeDownloaded) {
        data =
            <form className="form-horizontal" onSubmit={this.handleSubmit} id="shiftForm">

                <InputFieldForm
                    title="finish:"
                    name="finish"
                    onChange={this.handleFinishChange}
                    maxLength={5}
                    defaultValue={this.state.finish.value}
                    validation={this.validationFinishTime}
                    errorMessage="error"/>

                <div className="form-group">
                    <div className="col-sm-offset-2 col-sm-10">
                        <button type="submit" className="btn btn-success"> ADD
                        </button>
                    </div>
                </div>

            </form>
    }
    return(
            <div className="form-general">
                {data}
            </div>
    )
}
}

FormInputField

export default class FormInputField extends React.Component{

constructor(props) {
    super(props);
    this.state = {
        value : this.props.defaultValue ? this.props.defaultValue  : '',
        errorDisplay : st.DISPLAY_NONE,
        errorMessage : msg.MESSAGE_DEFAULT_ERROR,
    }
    this.validation = this.validation.bind(this);
    this.handleChange = this.handleChange.bind(this);
    this.handleBlur = this.handleBlur.bind(this);
}

handleChange(e){
    let valid = this.validation(e.target.value.trim());
    if (this.props.onChange){
        this.props.onChange(e, valid)
    }
}

validation(value){
    let errorDisplay = st.DISPLAY_NONE;
    let errorMessage = '';
    let valid = true;

    if (this.props.notShow != true) {
        if (this.props.required && jQuery.isEmptyObject(value)) {
            errorMessage = msg.MESSAGE_FIELD_IS_REQUIRED;
            errorDisplay = st.DISPLAY_BLOCK;
            valid = false;
        } else if (this.props.maxLength && value.trim().length > this.props.maxLength) {
            valid = false;
            errorMessage = this.props.maxLength + msg.MESSAGE_MAX_LENGTH;
            errorDisplay = st.DISPLAY_BLOCK;
        } else if (this.props.validation && !this.props.validation(value.trim())) {
            valid = false;
            errorDisplay = st.DISPLAY_BLOCK;
            errorMessage = this.props.errorMessage;
        }
    }
    this.setState({
        value : value,
        errorDisplay : errorDisplay,
        errorMessage : errorMessage
    })

    return valid;
}

handleBlur(e) {
    this.validation(e.target.value.trim());
}

    render(){
        let data;
        let readonly = undefined;
        if (this.props.readonly){
            readonly = true
        }
        if(this.props.notShow != true){
            data =  <div className="form-group">
                <label htmlFor = {this.props.name} className="col-sm-2 control-label">{this.props.title}</label>
                <div className="col-sm-10">

                    <input name={this.props.name}
                           type="text" className="form-control"
                           id={this.props.name}
                           placeholder={this.props.placeholder}
                           value={this.state.value}
                           onChange={this.handleChange}
                           onBlur={this.handleBlur}
                           disabled={this.props.disabled}
                           readOnly = {readonly}
                    />
                </div>
            </div>
        }

    return(
        <div>
            {data}
        </div>
    )
}

}

建議的解決方案:將您的事件處理程序綁定到組件上下文/范圍

(與構造函數中的其他語句相同,但我以前沒有使用過)

 this.validationFinishTime = ::this.validationFinishTime

或(我通常這樣做的方式;再次,在構造函數中):

 this.validationFinishTime = this.validationFinishTime.bind(this);

建議背后的推理:

這在這里有點猜測,因為我之前沒有見過這種語法( this.handleFinishChange = ::this.handleFinishChange ),但我猜測它將this的組件上下文綁定到方法,因此方法this.handleFinishChange可以引用this.setStatethis.state類的東西。

validationFinishTime沒有綁定到組件上下文,所以當它引用this.state.finish ,沒有引用this.state因為this指的是它被調用的上下文:這是 'validation' on 的內聯事件上下文<InputFieldForm/>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM