1. ホーム
  2. reactjs

[解決済み】React Formでpropsが変更されたときに状態を更新する

2022-04-07 04:36:57

質問

Reactのフォームで、状態を適切に管理するのに苦労しています。フォーム(モーダル)に時間入力フィールドがあります。初期値はステート変数として getInitialState 親コンポーネントから渡されます。これ自体は問題なく動作します。

問題は、親コンポーネントを通じてデフォルトのstart_timeの値を更新したいときに起こります。更新自体は、親コンポーネントで setState start_time: new_time . しかし、私のフォームでは、デフォルトの start_time で一度だけ定義されるので、値は決して変わりません。 getInitialState .

を使おうとしたことがあります。 componentWillUpdate を使用して強制的に状態を変更することができます。 setState start_time: next_props.start_time で、これは実際にうまくいったのですが、そのために 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

解決方法は?

<ブロッククオート <ブロッククオート

componentWillReceiveProps は react 16 以降は非推奨です。 getDerivedStateFromProps 代わりに

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

Reactには、このシナリオに対処するためのヒントがあります。 (注意:これは古い記事で、その後ウェブ上から削除されました。以下は、現在の コンポーネントプロップスに関するドキュメント ).

の状態を生成するためにpropsを使用します。 getInitialState は、真実のソース、つまり本当のデータがどこにあるのかが重複してしまうことがよくあります。これは getInitialState が呼び出されるのは、コンポーネントが最初に作成されたときだけです。

可能な限り、その場で値を計算し、後で同期が取れなくなってメンテナンスに支障をきたさないようにする。

基本的に、親の props を子の state は、prop の更新時に必ず 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 });
  }
}