首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >是否在状态更改时响应丢弃排队事件?

是否在状态更改时响应丢弃排队事件?
EN

Stack Overflow用户
提问于 2016-04-09 08:43:07
回答 2查看 1.1K关注 0票数 1

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

除了字段的onBlur和表单的‘`onSubmit同时被触发时,一切都正常工作。也就是说,我在字段中键入某项内容,然后立即单击submit按钮。

首先执行onBlur,如果不更改验证状态,则按预期执行onSubmit。但是,如果onBlur更改了状态,则onSubmit函数永远不会被称为

因此,我的问题是:在组件中设置状态是否清除了任何排队事件,是否有可能解决此问题?

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

代码语言:javascript
运行
复制
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'));

和一个JSFiddle,它应该允许您自己看到错误。任何帮助都是值得感激的。

EN

回答 2

Stack Overflow用户

发布于 2016-04-09 11:51:04

感谢马诺洛证实了我的怀疑,那就是状态的变化抹掉了事件队列。我想我已经找到了一个解决方案,现在可以:

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

代码语言:javascript
运行
复制
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主体时才执行它:

代码语言:javascript
运行
复制
handleBlur(event) {
    if (!event.relatedTarget || event.relatedTarget.id !== 'submit') {
        console.log("blur")

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

        this.setState({ shouldShowError: isEmpty }) 
    }
}
票数 1
EN

Stack Overflow用户

发布于 2016-04-09 10:23:04

是的,更改组件中的状态可以清除任何排队事件,因为状态更改会导致重新呈现整个组件,并清除和重新附加事件。

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

如果希望保留示例行为,则可以在显示错误且没有错误时在onBlur回调中提交表单:

代码语言:javascript
运行
复制
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'));

https://jsfiddle.net/2r9ua1n1/3/

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36514629

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档