2016-04-09 6 views
1

私は簡単な検証でReactフォームコンポーネントを作っています。各フィールドはぼかしで検証され、フォームには単純なonSubmit関数があります。ブール値は、フィールドにエラーメッセージが表示されるかどうかの状態に格納され、これは検証中に更新されます。Reactは、状態が変化したときにキューに入れられたイベントを破棄しますか?

フィールドのonBlurとフォームのonSubmitが同時にトリガーされる場合を除いて、すべてが正常に動作します。私。私はフィールドに何かを入力し、すぐに送信ボタンをクリックします。

最初に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')); 

そして、あなたは自分のためにエラーが表示できるようにする必要がありJSFiddle

は、ここに私のコードの簡易版です。どんな助けでも常に感謝しています。状態変化が全体成分が再レンダリングなることを引き起こし、そしてイベントがをクリアし再取り付けされるので、明確なコンポーネントの状態を変更

答えて

0

はいは、イベントをキューに入れられました。

ぼかし1ではなく、送信イベントコールバックで検証を行います。ユーザーが入力中に検証する場合は、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')); 

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

+0

は、まあ、私はそのような場合はうれしい、それはちょうど私が非常識つもりはないです。あなたの提案に関しては、onKeyUpやonChangeが電子メールフィールドのエラーメッセージを途中で表示するため、要件の一部にはぼかしの検証が含まれています。また、フォームには8つのフィールドがあります。したがって、送信時にのみ検証することは特にユーザーフレンドリーではありません。 – Tom

+0

しかし、検証が失敗したときにフォームを送信する必要はなく、フォームを送信するときに状態が変化しない場合は、フォームが送信されます(送信イベントコールバックが実行されます)。 – Manolo

+0

それは本当です。この問題は、特にフィールドのエラーメッセージが表示されているときにユーザーがそれを修正してから送信をクリックしたときに発生します。このシナリオでは、フォームは有効ですが、onBlurの状態変更がonSubmitイベントを取り消すので、フォームは有効ですが、フォームは送信されません。 – Tom

1

感謝イベントキューをワイプするのは状態の変化であるという疑いがあります。

onBlurボディとonSubmitボディの両方を実行する必要がある場合は、onBlurボディをsetTimeoutにラップしてタスクキューに入れて実行することができますあなたが)あなたはタイムアウトの外に必要な値を抽出、または(event.persistを呼び出すためのいずれかが必要になりますので、中には非同期に、あなたがすることができないデフォルトアクセスでイベントを反応させること

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

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

     const isEmpty = value === "" 

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

注:onSubmit検証の後。

私のonSubmitがフォームを検証する際にonBlur本体を実行する必要はありません。ちょっと読んだ後、私はあなたがフォーカスが移動されたコンポーネントにアクセスするためにevent.relatedTargetを呼び出すことができることを知りました。それは送信ボタンであれば、私は確認することができ、それがない場合にのみ、onBlurイベントのボディを実行します。

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

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

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

これはまさに私が提案しようとしていたものです... – Manolo

関連する問題