2016-11-23 3 views
0

完全な画像はgistを参照してください。反応で動的に作成されたカスタムフォームコンポーネント

基本的に私はこのフォームを持つことになります:あなたはプラスをクリックすると

form

を、別の行には、日付と時間フィールドのドロップダウンで表示されます。

フォームに入力を追加するコードを作成できますが、実際に値を更新する個々のコンポーネント(selectTimeInputが1行です)に問題があります。

MultipleDayTimeInputonChangeが正しいデータを受信して​​いますが、それは更新されていない表示です。私は非常に反応したので、ディスプレイが更新されない原因はわかりません....

propsで渡されたものが存在しないため、SelectTimeInputレンダリング機能が呼び出されていないと思います更新されましたが、私はそれを達成するための正しい方法が不明です。それについて考えて

は、setStateMultipleDayTimeInputonChangethis.state.inputsから除去し、火災にレンダリング強制するために再び追加する必要がありますを変更入力に呼び出される必要がありません...これは少しです私には不格好...

+0

あなたはコードを投稿できますか?私はそれが何であるかのアイデアを持っていますが、私はいくつかのコードを参照する必要があります – jacoballenwood

+0

右のポストの上部に要点のリンクです! @jakeaaron –

+0

わかりました、私の悪い.. – jacoballenwood

答えて

3

stateの入力の表示値を更新する場合は、this.setStateを使用して状態データを変更し、新しいデータを再レンダリングする必要があります。 input.key = valueを使うのは正しい方法ではありません。正しく
あなたがについて SETSTATE()を知っておくべき3つのものがあります状態を使用して

は、例えば直接
状態を変更しないでください、これはありません再描画 コンポーネントは以下となります。

//間違った
this.state.comment =「こんにちは」;
代わりに、使用SETSTATE():

//正しい
this.setState({コメント: 'ハロー'})。
がthis.stateを割り当てることができる唯一の場所はコンストラクタです。

は直接のFacebookからhere

を続きを読む私は実際にかかわらず、あなたのコードの再構築の少しをお勧めします。あなたの国の価値の一部としてコンポーネントを持つことは、実際には勧められません。私は、あなたの異なる入力をthis.state.inputsのデータオブジェクトとしてお勧めし、データをループし、レンダリングメソッドでそれぞれの表示を構築します。

:このような何かを、あなたのレンダリングで

inputs = { 
    1: { 
     selectedTime: 0:00, 
     selectedValue: 2 
    } 
} 

を使用すると、1つのあなたのthis.state.inputs入力(とあなたの入力はキーにアクセスするためのオブジェクトであると仮定)を持っているとします。このような

render() { 
    let inputs = Object.keys(this.state.inputs).map((key) => { 
     let input = this.state.inputs[key] 
     return (<SelectTimeInput 
      key={key} 
      name={'option_' + key} 
      placeholder={this.props.placeholder} 
      options={this.props.options} 
      onChange={this.onChange.bind(this, key)} 
      timeValue={input.selectedTime} 
      selectValue={input.selectedValue} 
     />)  
    )} 
    return (
     <div> 
      <button className="button" onClick={this.onAddClick}><i className="fa fa-plus" /></button> 

      { inputs } 
     </div> 
    ); 
} 

どのキーをonChangeにバインドしているので、どの入力を更新するかわかります。今、あなたのonChange機能で、あなただけのSETSTATEで正しい入力の値を設定します。

onChange(event, key) { 
    this.setState({ 
     inputs: Immutable.fromJS(this.state.inputs).setIn([`${key}`, 'selectedTime'], event.target.value).toJS() 

     // or 
     inputs: Object.assign(this.state.inputs, Object.assign(this.state.inputs[key], { timeValue: event.target.value })) 

    }) 
} 

これがテストされていませんが、基本的にこの不変の文がthis.state.inputsのコピーを作成して設定しようとしていますキーに一致するオブジェクトの内部のselectedTime値をevent.target.valueに設定します。状態が更新され、再レンダリングがトリガされ、レンダリングで入力を再びループすると、新しい時間値がtimeValueとしてコンポーネントに使用されます。

Object.assign編集では、テストされていませんが、詳細はこちら[こちら]をご覧ください。 2基本的に、この文は、新しいtimeValue値をthis.state.inputs [key]オブジェクトとマージし、その新しいオブジェクトをthis.state.inputsオブジェクト全体とマージします。

これは意味がありますか?

+0

ええ、それは私のアプローチよりもfarrrrrrrに見えます、私はそれが簡単でなければならないことを知っていた! –

+0

あなたは純粋なjsの '不変'代替を表示できますか?私はまだここに「不変」を固執し始めたくない。 –

+0

yeah lemme編集 – jacoballenwood

0

私はMultipleDayTimeInputonChangeを変更:

onChange(event) { 
    const comparisonKey = event.target.name.substring(event.target.name.length - 1); 
    const input = this.getInputState(comparisonKey); 

    input.selected = event.target.value; 
    input.display = this.renderTimeInput(input); 

    let spliceIndex = -1; 
    for (let i = 0; i < this.state.inputs.length; i++) { 
     const matches = inputFilter(comparisonKey)(this.state.inputs[i]); 

     if (matches) { 
      spliceIndex = i; 
      break; 
     } 
    } 

    if (spliceIndex < 0) { 
     throw 'error updating inputs'; 
    } 

    this.setState({ 
     inputs: [...this.state.inputs].splice(spliceIndex, 1, input) 
    }); 
} 

キーポイントは次のとおりです。

// re render the input 
input.display = this.renderTimeInput(input); 

// set the state by copying the inputs and interchanging the old input with the new input.... 
this.setState({ 
    inputs: [...this.state.inputs].splice(spliceIndex, 1, input) 
}); 

this.state.inputsの入力にはinputというオブジェクト参照があるので、実際には[...this.states.inputs]で十分でしょうか?

関連する問題