2016-06-28 11 views
4

私は動的な要素のコレクションを持っているので、コレクションの内容が何であるかはわかりません。これらのチェックボックスを動的にレンダリングして、デフォルトですべてチェックします。ボックスのチェックを外すと、レンダリングで別のマップ機能がトリガーされます。 (基本的に私のフィルターです)ReactJS:状態からの動的チェックボックス

私は状態の設定に苦しんでいます。 私はAPI呼び出しによってComponentWillMount時の初期状態を設定したい以下、考えていた:

scenario 1 (arrays): 

this.state { 
    checkboxes: [value1, value2, value3], 
    checkedcheckboxes: [value1, value2] 
} 

それから私はcheckcheckboxes状態を変更するためにreact.addons.update機能を使用することができます。欠点は、自分のチェックボックスをレンダリングする際にチェックする必要があるかどうかをチェックするために、すべてのチェックボックスでindexOfを指定してcheckcheckboxes配列をループする必要があることです。

scenario 2 (object): 

this.state { 
    checkboxes: { 
     value1: true, 
     value2: true, 
     value3: false 
} 

私がSETSTATEに計算フィールドを使用する必要があるため、それは難しく、(私は推測)動作するようになり、私は動的なキーを持っている。この方法で、。私はこれが自分のパフォーマンスに悪影響を及ぼす可能性があるという印象を受けました。

このパターンにはベストプラクティスがありますか?

ありがとうございました!

答えて

12

私はおそらくあなたの状態を(チェックボックスを表す)オブジェクトの配列とあなたのフィルタを表す文字列を含むように設定します。各チェックボックスオブジェクトには、ラベルのテキストとチェックボックスの値という2つのプロパティが含まれています。

初期状態では、この配列を空にしたい場合は、componentDidMountライフサイクルの間にAPI呼び出しを実行し、受信した情報を含めるように状態を設定します。これらのチェックボックスを描画するためにあなたのコンポーネントのために

constructor(props) { 
    super(props); 

    this.state = { 
     checkboxes: [], 
     filter: 'ALL' 
    }; 

    //each checkbox would take the form of {label: 'some label', checked: true} 
} 

componentDidMount() { 
    getData(response => { //some API call 
     this.setState({ 
      checkboxes: response.body 
     }); 
    }); 
} 

、それはあなたの状態であなたのチェックボックスオブジェクトが実際のDOM要素にどのように関係するかを理解する必要があります。これを行うには.mapを利用するヘルパー関数を作成することができます。 .filterを利用して、状態の各オブジェクトにフィルタを適用し、フィルタに一致しないオブジェクトを取り除くこともできます。

function renderCheckboxes() { 
    const {checkboxes, filter} = this.state; 

    return checkboxes 
     .filter(checkbox => 
      filter === 'ALL' || 
      filter === 'CHECKED' && checkbox.checked || 
      filter === 'UNCHECKED' && !checkbox.checked 
     ) 
     .map((checkbox, index) => 
      <div> 
       <label> 
        <input 
         type="checkbox" 
         checked={checkbox.checked} 
         onChange={toggleCheckbox.bind(this, index)} 
        /> 
        {checkbox.label} 
       </label> 
      </div> 
     ); 
} 

各チェックボックスのonChange属性には、一部の機能が割り当てられていることに注意してください。 Controlled Componentを作成するので、checked属性を使用してレンダリングするすべてのチェックボックスにこれを指定する必要があります。状態は、個々のコンポーネントがチェックされているかどうかを制御します。あなたのtoggleCheckbox関数は次のようなものに見えることがあります。

function toggleCheckbox(index) { 
    const {checkboxes} = this.state; 

    checkboxes[index].checked = !checkboxes[index].checked; 

    this.setState({ 
     checkboxes 
    }); 
} 

をまた別の文字列にあなたのフィルタを設定する関数を作成すると便利かもしれません:

function updateFilter(filter) { 
    this.setState({ 
     filter 
    }); 
} 

最後に、あなたはあなたにこれらの関数を使用することができます

render() { 
    return (
     <div> 
      {renderCheckboxes.call(this)} 
      <div> 
       <h4>Filters ({this.state.filter})</h4> 
       <a href="#" onClick={updateFilter.bind(this, 'ALL')}>ALL</a> 
       &nbsp;|&nbsp; 
       <a href="#" onClick={updateFilter.bind(this, 'CHECKED')}>CHECKED</a> 
       &nbsp;|&nbsp; 
       <a href="#" onClick={updateFilter.bind(this, 'UNCHECKED')}>UNCHECKED</a> 
      </div> 
     </div> 
    ); 
} 
:あなたのフィルタのステータスを更新するためにあなたのチェックボックスだけでなく、リンクを表示する render機能は、(私はまた、各フィルタのリンクを分離するためにいくつかの非破壊スペースを追加しました)ここ

は、この作業の例だ - マイナスAPIの呼び出し:

https://jsbin.com/bageyudaqe/edit?js,output

は、この情報がお役に立てば幸い!

+0

3回WOW!これは本当に素晴らしい答えです、多くのありがとうございます。 – user3611459

+0

お手伝いします!あなたの問題を解決した場合は、この回答を受け入れるようにしてください:) –

+0

はい、私は持っている、あなたは私のフォローアップの質問を見てみたいですか? ;-) – user3611459

関連する問題