2017-03-26 44 views
3

Reactについて読んだ後、私はサンプルプロジェクトでいくつかの簡単なアイデアをテストすることにしました。しかし、setStateが期待どおりに動作しないのは驚いた。 setStateは状態を変更しません。私がアップデートアドオンを使用していても、setStateを状態に変更すると動作します!私も新しい状態オブジェクトを記録しており、それは正しいです。何が間違っているのか分かりません!私はあなたの助けに感謝します。反応setStateは反応の更新を使用していても状態を変更しません。

import React from 'react'; 
import update from 'react-addons-update'; 
class WebFooterSubscription extends React.Component { 
    //======================================================== 
    constructor(props) { 
     super(props); 
     this.state = { 
      formIsValid: false, 
      email: { 
       value: "", 
       focused: false, 
       touched: false, 
       isValid: false, 
       error: "Enter your email" 
      }, 
      mobile: { 
       value: "", 
       focused: false, 
       touched: false, 
       isValid: false, 
       error: "Enter your mobile" 
      } 
     }; 
    } 
    //================================================================= 
    componentDidUpdate(prevProps, prevState) {} 
    //======================================================== 
    onBlur(event) { 
     if ('mobile1' === event.target.id) { 
      let newState = { ...this.state, 
       mobile: { ...this.state.mobile, 
        value: event.target.value, 
        focused: false, 
        touched: true 
       } 
      }; 
      console.log("mobile blur:", JSON.stringify(newState)); 
      this.setState(newState); // this seems not to work! 
     } 
     if ('email1' === event.target.id) { 
      let newState = update(this.state, { 
       email: { 
        value: { 
         $set: event.target.value 
        }, 
        touched: { 
         $set: true 
        }, 
        focused: { 
         $set: false 
        } 
       } 
      }); 
      console.log("email blur:", JSON.stringify(newState)); 
      this.setState(newState); // this seems not to work! 
     } 
     this.cmdValidate(); 
    } 
    //======================================================== 
    onFocus(event) { 
     console.log("focus occured"); 
     if ('mobile1' === event.target.id) { 
      let newState = { ...this.state.mobile 
      }; 
      newState.focused = true; 
      newState.touched = true; 
      this.setState({ ...this.state, 
       mobile: newState 
      }); 
     } 
     if ('email1' === event.target.id) { 
      this.setState({ ...this.state, 
       email: { ...this.state.email, 
        touched: true, 
        focused: true 
       } 
      }); 
     } 
    } 
    //======================================================== 
    cmdValidate() { 
     // console.log("length " ,this.state.mobile.value.length); 
     if (this.state.mobile.value && this.state.mobile.value.length === 11) { 
      this.setState({ ...this.state, 
       mobile: { ...this.state.mobile, 
        isValid: true, 
        error: "" 
       } 
      }); 
     } else { 
      this.setState({ ...this.state, 
       mobile: { ...this.state.mobile, 
        isValid: false, 
        error: "Enter your cell phone number correctly" 
       } 
      }); 
     } 
     if (this.state.email.value) { 
      let isValidEmail = true; 
      if (isValidEmail) { 
       this.setState({ ...this.state, 
        email: { ...this.state.email, 
         isValid: isValidEmail 
        } 
       }); 
      } else { 
       this.setState({ ...this.state, 
        email: { ...this.state.email, 
         isValid: false, 
         error: "Your email is not correct" 
        } 
       }); 
      } 
     } else { 
      this.setState({ ...this.state, 
       email: { ...this.state.email, 
        isValid: false, 
        error: "Enter email" 
       } 
      }); 
     } 
     if (this.state.email.isValid && this.state.mobile.isValid) { 
      this.setState({ ...this.state, 
       formIsValid: true 
      }); 
     } else { 
      this.setState({ ...this.state, 
       formIsValid: false 
      }); 
     } 
    } 
    //======================================================== 
    onSubmitClick(event) { 
     //this.setState({count : this.state.count + 1}); 
     event.preventDefault(); 
    } 
    render() { 
     return (<form name="subscriptionForm" id="subscriptionForm" className="form" method="post"> 
           <div className={`form-group ${this.state.email.touched && !this.state.email.isValid ? ' has-danger' : ''}`}> 
            <div className="col-md-12 "> 
             <div className="input-group" > 
              <input id="email1" name="email1" onBlur={(event)=>this.onBlur(event)} onFocus={(event)=>this.onFocus(event)} className="form-control" placeholder="email" type="text" /> 
              <div className="input-group-addon"><img src="assets/images/icons/svg/opened-email-envelope.svg" alt="email" width="24px" height="24px" /></div> 
             </div> 
             <div className="help-block" hidden={!this.state.email.focused}> 
               {this.state.email.touched && ((this.state.email.error && <span>{this.state.email.error}</span>))} 
             </div> 

            </div> 
           </div> 
           <div className={`form-group ${this.state.mobile.touched && !this.state.mobile.isValid ? ' has-danger' : ''}`}> 
            <div className="col-md-12 "> 
             <div className="input-group" > 
              <input id="mobile1" name="mobile1" className="form-control" onBlur={(event)=>this.onBlur(event)} onFocus={(event)=>this.onFocus(event)} placeholder="cell phone" type="text" /> 
              <div className="input-group-addon"><img src="assets/images/icons/svg/talking2.svg" alt="cell phone" width="24px" height="24px" /></div> 
             </div> 
            </div> 
           </div> 
           <div className="leftButton"> 
            <button type="submit" onClick={(event)=> this.onSubmitClick(event)} className="btn btn-primary" >Subscribe</button> 
           </div> 
            <div> 
             {JSON.stringify(this.state)}disabled={!this.state.formIsValid} 
            </div> 
          </form>); 
    } 
} 
export default WebFooterSubscription; 
+0

可能な重複すぐに状態?](http://stackoverflow.com/questions/42593202/why-calling-setstate-method-doesnt-mutate-the-state-immediately) –

答えて

0

setStateが非同期で、すぐにログに記録しているためです。レンダーが呼び出されるまでに更新されます。

1
  • setStateは非同期操作なので、設定した直後に新しい状態にアクセスしようとすると、更新された状態にならないことがあります。このようになり
  • だから、それを設定した後、新たな状態にアクセスするために、あなたはコールバック関数を介してアクセスする必要がある、: -

    this.setState({// ここであなたは新しい状態を提供あなたの場合は}、()=> {// ここにあなたが}それにアクセス)

  • あなたはonBlurイベント機能では、この方法でそれをアクセスすることができます。溶液上の

onBlur(event){ 
 
let newState 
 
     if('mobile1'===event.target.id){ 
 
      newState= {...this.state,mobile:{...this.state.mobile ,value:event.target.value, focused:false, touched:true}}; 
 
      console.log("mobile blur:" ,JSON.stringify(newState)); 
 
      
 
     } 
 
     if('email1'===event.target.id){ 
 
      newState = update(this.state, { email: { value: {$set: event.target.value} ,touched: {$set: true},focused:{$set:false}} }); 
 
      console.log("email blur:" ,JSON.stringify(newState)); 
 
     } 
 
     this.setState(newState,()=>{this.cmdValidate()}) 
 
     
 
    }

  • 希望あなたの問題を解決する可能性があります..... :) [なぜSETSTATEメソッドを呼び出すと、変異していないの
+0

ありがとうRajat.I kno setStateはasync.butですが、私はlogging.Iを使っていません。私はJSON.Stringifyを使ってレンダリングメソッド全体の状態を表示しました。最後に、レンダリングメソッドで状態の更新を表示する必要があります。 – Alex

関連する問題