Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript React是否在状态更改时放弃排队事件?_Javascript_Reactjs_Forms_Validation_Dom Events - Fatal编程技术网

Javascript React是否在状态更改时放弃排队事件?

Javascript React是否在状态更改时放弃排队事件?,javascript,reactjs,forms,validation,dom-events,Javascript,Reactjs,Forms,Validation,Dom Events,我正在制作一个带有简单验证的React表单组件。每个字段都在模糊上进行验证,表单有一个简单的onSubmit函数。布尔值存储在字段是否应显示错误消息的状态中,并在验证期间更新 除了字段的onBlur和表单的`onSubmit同时被触发外,其他一切都正常工作。i、 e.我在字段中键入一些内容,然后立即单击“提交”按钮 首先执行onBlur,如果验证状态没有发生变化,则按预期执行onSubmit。但是,如果onBlur更改状态,则永远不会调用onSubmit函数 所以我的问题是,;组件中的设置状态是

我正在制作一个带有简单验证的React表单组件。每个字段都在模糊上进行验证,表单有一个简单的
onSubmit
函数。布尔值存储在字段是否应显示错误消息的状态中,并在验证期间更新

除了字段的
onBlur
和表单的`onSubmit同时被触发外,其他一切都正常工作。i、 e.我在字段中键入一些内容,然后立即单击“提交”按钮

首先执行
onBlur
,如果验证状态没有发生变化,则按预期执行
onSubmit
。但是,如果
onBlur
更改状态,则永远不会调用
onSubmit
函数

所以我的问题是,;组件中的设置状态是否清除任何排队事件,是否有任何可能的解决方案

以下是我的代码的简化版本:

class SimpleForm extends React.Component {
    constructor(props) {
        super(props);

        this.handleBlur = this.handleBlur.bind(this);

        this.state = { shouldShowError: false }
    }

    handleBlur(event) {
        console.log("blur")

        const isEmpty = event.target.value === ""

        this.setState({ shouldShowError: isEmpty })
    }

    handleSubmit(event) {
        event.preventDefault()

        console.log("submit")
    }

    render() {
        return ( 
            < form onSubmit = { this.handleSubmit} >
                < input type = "text" onBlur = { this.handleBlur } /> 
                { this.state.shouldShowError ? < p > This field is required. < /p> : null } 
                < button type = "submit" > Submit < /button > 
            < /form>
        )
    }
};

ReactDOM.render(< SimpleForm / >, document.getElementById('container'));
类SimpleForm扩展了React.Component{ 建造师(道具){ 超级(道具); this.handleBlur=this.handleBlur.bind(this); this.state={shouldbarhorror:false} } 车把(活动){ 控制台日志(“模糊”) const isEmpty=event.target.value==“” this.setState({shouldbarhorror:isEmpty}) } handleSubmit(事件){ event.preventDefault() 控制台日志(“提交”) } render(){ 报税表(
{this.state.shouldBrower?此字段是必需的。

:null}
) } }; ReactDOM.render(,document.getElementById('container');
一个可以让你自己看到错误的地方。欢迎提供任何帮助。

是的,更改组件中的状态将清除所有排队事件,因为状态更改将导致整个组件重新呈现,并且事件将被清除并重新附加

我将在submit事件回调中进行验证,而不是在blur事件回调中进行验证。如果要在用户键入时进行验证,可以使用
onKeyUp

如果要保留示例行为,可以在显示错误且无错误时在
onBlur
回调中提交表单:

class SimpleForm extends React.Component {
    constructor(props) {
        super(props);

        this.handleBlur = this.handleBlur.bind(this);

        this.state = { shouldShowError: false }
    }

    handleBlur(event) {
        console.log("blur")

        const isShowingError = this.state.shouldShowError;
        const isEmpty = event.target.value === ""

        if (isShowingError && !isEmpty) {
          console.log("submit the form");
        }
        this.setState({ shouldShowError: isEmpty })
    }

    handleSubmit(event) {
        event.preventDefault()

        console.log("submit")
    }

    render() {
        return ( 
          < form onSubmit = { this.handleSubmit} >
                < input type = "text" onBlur = { this.handleBlur } /> 
                { this.state.shouldShowError ? < p > This field is required. < /p> : null } 
                < button type = "submit" > Submit < /button > 
            < /form>
        )
    }
};

ReactDOM.render(< SimpleForm / >, document.getElementById('container'));
类SimpleForm扩展了React.Component{ 建造师(道具){ 超级(道具); this.handleBlur=this.handleBlur.bind(this); this.state={shouldbarhorror:false} } 车把(活动){ 控制台日志(“模糊”) const isShowingError=this.state.shouldFlowerRor; const isEmpty=event.target.value==“” if(isShowingError&!isEmpty){ 控制台日志(“提交表格”); } this.setState({shouldbarhorror:isEmpty}) } handleSubmit(事件){ event.preventDefault() 控制台日志(“提交”) } render(){ 报税表(
{this.state.shouldBrower?此字段是必需的。

:null}
) } }; ReactDOM.render(,document.getElementById('container');
感谢Manolo确认了我的怀疑,即是状态更改清除了事件队列。我想我已经找到了一个暂时可行的解决方案:

如果需要同时执行onBlur和onSubmit主体,可以在setTimeout中包装onBlur主体,以便将其放入任务队列并在onSubmit之后执行:

handleBlur(event) {
    const value = event.target.value

    setTimeout(() => {
        console.log("blur")

        const isEmpty = value === ""

        this.setState({ shouldShowError: isEmpty }) 
    }, 10)
}
请注意,在react中,默认情况下无法异步访问事件,因此需要提取超时之外所需的值,或者调用event.persist()

我不需要onBlur主体来执行,因为onSubmit也会验证表单。经过一点阅读,我发现您可以调用event.relatedTarget来访问焦点转移到的组件。因此,我可以检查它是否是submit按钮,如果不是,则仅执行onBlur主体:

handleBlur(event) {
    if (!event.relatedTarget || event.relatedTarget.id !== 'submit') {
        console.log("blur")

        const isEmpty = event.target.value === ""

        this.setState({ shouldShowError: isEmpty }) 
    }
}

我很高兴事情是这样的,不仅仅是我疯了。关于您的建议,部分要求是对blur进行验证,因为onKeyUp或onChange会过早地显示电子邮件字段的错误消息。此外,表单中有8个字段,因此仅在提交时进行验证对用户来说并不特别友好。但是,验证失败时,您不需要提交表单,如果提交表单时状态在模糊上没有改变,则表单将被提交(提交事件回调将被执行)。这是正确的。当显示字段的错误消息时,用户会更正该错误消息,然后单击submit。在这种情况下,表单应该提交,因为表单是有效的,但它不是,因为onBlur中的状态更改正在取消onSubmit事件。不幸的是,我也不能执行您的最新建议。表单应仅在单击提交按钮时提交。