2015-09-05 13 views
59

Reactフォームに問題があり、状態を適切に管理しています。私は時間入力フィールドをフォームで(モーダルで)持っています。初期値はgetInitialStateの状態変数として設定され、親コンポーネントから渡されます。これ自体はうまくいきます。Reactフォームの小道具の状態の更新

問題は、親コンポーネントを介してデフォルトのstart_time値を更新するときに発生します。更新自体は親コンポーネントでsetState start_time: new_timeによって行われます。しかし、私のフォームでは、デフォルトのstart_time値は決して変更されません。それは一度だけgetInitialStateに定義されているからです。

私は実際に動作したsetState start_time: next_props.start_timeによって状態を強制的に変更するのにcomponentWillUpdateを使用しようとしましたが、私にはUncaught RangeError: Maximum call stack size exceededのエラーが出ました。

私の質問は、この場合の状態を更新する正しい方法は何ですか?どういうわけか、この間違いを考えていますか?

現在のコード:

@ModalBody = React.createClass 
    getInitialState: -> 
    start_time: @props.start_time.format("HH:mm") 

    #works but takes long and causes: 
    #"Uncaught RangeError: Maximum call stack size exceeded" 
    componentWillUpdate: (next_props, next_state) -> 
    @setState(start_time: next_props.start_time.format("HH:mm")) 

    fieldChanged: (fieldName, event) -> 
    stateUpdate = {} 
    stateUpdate[fieldName] = event.target.value 
    @setState(stateUpdate) 

    render: -> 
    React.DOM.div 
     className: "modal-body" 
     React.DOM.form null, 
     React.createElement FormLabelInputField, 
      type: "time" 
      id: "start_time" 
      label_name: "Start Time" 
      value: @state.start_time 
      onChange: @fieldChanged.bind(null, "start_time”) 

@FormLabelInputField = React.createClass 
    render: -> 
    React.DOM.div 
     className: "form-group" 
     React.DOM.label 
     htmlFor: @props.id 
     @props.label_name + ": " 
     React.DOM.input 
     className: "form-control" 
     type: @props.type 
     id: @props.id 
     value: @props.value 
     onChange: @props.onChange 

答えて

144

私が正しく理解していれば、あなたは自身の状態に割り当てModalBodyコンポーネントにダウンstart_timeを通過している親コンポーネントがありますか?子コンポーネントではなく、親からその時間を更新したいとします。

React has some tips on dealing with this scenario.(これは以前の記事で、ウェブから削除されています。現在のdoc on component propsへのリンクです)。

getInitialStateに状態を生成するために小道具を使用すると、実際のデータが存在する場所である「真実の源」が重複することがよくあります。これは、getInitialStateが最初にコンポーネントが作成されたときにのみ呼び出されるためです。

可能であれば、オンザフライで値を計算して、あとで同期が外れてメンテナンスに問題が発生しないようにしてください。あなたが親のprops子のstate renderメソッドに割り当てたときに、基本的に

は、常に小道具更新時に呼び出されません。 componentWillReceivePropsメソッドを使用して手動で呼び出す必要があります。

componentWillReceiveProps(nextProps) { 
    // You don't have to do this check first, but it can help prevent an unneeded render 
    if (nextProps.startTime !== this.state.startTime) { 
    this.setState({ startTime: nextProps.startTime }); 
    } 
} 
+1

ありがとう。それは助けてくれるよ – Sukanta

+0

"あなたはその時間を子コンポーネントではなく親から更新したい。"逆に? – ram4nd

+0

それから私は何かが分からない限り、子コンポーネント内の単純な 'setState()'になります。 –

関連する問題