2017-08-17 4 views
2

React?の以下のような単純化のベストプラクティスがありますか?Reactでの繰り返しコードの簡略化

const Checkboxes = React.createClass({ 
    getInitialState: function() { 
    return { 
     checkboxes: [false, false, false, ...] 
    }; 
    }, 

    selectCheckbox: function (index) { 
    let checkboxes = this.state.checkboxes.slice(); 
    checkboxes[index] = !checkboxes[index]; 
    this.setState({ 
     checkboxes: checkboxes 
    }); 
    }, 

    render: function() { 
    return (
     <div> 
     <input type="checkbox" checked={this.state.checkboxes[0]} onChange={() => this.selectCheckbox(0)} /> 
     <input type="checkbox" checked={this.state.checkboxes[1]} onChange={() => this.selectCheckbox(1)} /> 
     <input type="checkbox" checked={this.state.checkboxes[2]} onChange={() => this.selectCheckbox(2)} /> 
     ... 
     </div> 
    ); 
    } 
}); 

を私は新しいです:

getInitialState: function() { 
    return { 
    checkbox1: false, 
    checkbox2: false, 
    checkbox3: false, 
    ... 
    }; 
}, 

selectCheckbox1: function() { 
    this.setState({ 
    checkbox1: !this.state.checkbox1 
    }); 
}, 

selectCheckbox2: function() { 
    this.setState({ 
    checkbox2: !this.state.checkbox2 
    }); 
}, 

selectCheckbox3: function() { 
    this.setState({ 
    checkbox3: !this.state.checkbox3 
    }); 
}, 

... 

render: function() { 
    return (
    <div> 
     <input type="checkbox" checked={this.state.checkbox1} onChange={this.selectCheckbox1} /> 
     <input type="checkbox" checked={this.state.checkbox2} onChange={this.selectCheckbox2} /> 
     <input type="checkbox" checked={this.state.checkbox3} onChange={this.selectCheckbox3} /> 
     ... 
    </div> 
); 
} 

は例えば、私は、チェックボックス更新する代わりに、個々のフィールドの状態のための配列を使用して区別するために、インデックスパラメータをとる汎用関数を作成することができますReactとJavaScriptを使用しているので、ここでは舞台裏で起こっているトレードオフを正確に把握していません。第2は第1よりも改善ですか?どちらが好ましいのですか?

+0

この質問はまだのように未解決示しています。それは...ですか? – jonahe

答えて

1

私はこのようなものだろう:

class App extends Component { 
    constructor(props) { 
    super(props); 
    this.state = { 
     checkboxes: { 
     cheese: false, 
     lettuce: false, 
     tomatoe: false 
     } 
    }; 
    } 

    handleChange = e => { 
    const checkboxId = e.target.id; 
    this.setState({ 
     checkboxes: { 
     ...this.state.checkboxes, 
     [checkboxId]: !this.state.checkboxes[checkboxId] 
     } 
    }); 
    }; 

    render() { 
    return (
     <div> 
     {Object.entries(this.state.checkboxes).map(([key, val]) => { 
      return (
      <div key={key}> 
       <input 
       type="checkbox" 
       checked={val} 
       id={key} 
       onChange={this.handleChange} 
       /> 
       <label> 
       {key} 
       </label> 
      </div> 
     ); 
     })} 
     </div> 
    ); 
    } 
} 

これは、より明確かつ簡単に物事が従うことになり、あなたがレンダリングするたびに新しい匿名関数を作成していないという利点もあります。

+0

各レンダリングで新しい無名関数を作成する際の欠点は何ですか?彼らはいつゴミ収集されますか? –

+1

@ JoshBroadhurst基本コンポーネントが 'shouldComponentUpdate'の小道具を比較できるようにすることがベストプラクティスです。匿名関数は常に異なっています – thedude

+0

大丈夫です、それを得ました。ありがとう。マップ呼び出し( '([key、val])=> {...}')にまだ無名関数がありますが、それは小道具として渡されません。その無名関数はレンダリングサイクルにどのような影響を与えますか? –

3

第2の方法は、最初の方法よりもはるかに良い方法です。あなたはそれで安全に行くことができます。

それ以外に、配列マップを使用して、レンダリング機能で毎回繰り返さずにチェックボックスをレンダリングすることもできます。

render: function() { 
    return (
     <div> 
     {this.state.checkboxes.map((c, i) => { 
      return (
       <input key={i} type="checkbox" checked={c} onChange={() => this.selectCheckbox(i)} /> 
      ); 
     })} 
     </div> 
    ); 
    } 
1

最初の例のように(配列ではなくオブジェクト内に)名前の付いたチェックボックスを使用することをお勧めします。しかし、それはユースケースによって異なる可能性があります。 Prakash-sharmaが指摘しているように、配列として名前を付けるのではなく、それらの上にマップできるという利点があります。

これは私が(配列のチェックボックスの値を格納せずに)コールバック関数の宣言の重複を減らすためにそれを行うだろうかです:

const Checkboxes = React.createClass({ 
    getInitialState: function() { 
    return { 
     checkbox1: false, 
     checkbox2: false, 
     checkbox3: false 
    }; 
    }, 

    selectCheckbox: function (checkboxNr) { 
    // return a callback with the checkboxNr set 
    return() => { 
     this.setState({ 
     [checkboxNr]: !this.state[checkboxNr] 
     }); 
    } 
    }, 

    render: function() { 
    const {checkboxes1, checkboxes2, checkboxes3} = this.state; 
    return (
     <div> 
     <input type="checkbox" checked={checkboxes1} onChange={ this.selectCheckbox("checkbox1") } /> 
     <input type="checkbox" checked={checkboxes2} onChange={ this.selectCheckbox("checkbox2") } /> 
     <input type="checkbox" checked={checkboxes3} onChange={ this.selectCheckbox("checkbox3") } /> 
     </div> 
    ); 
    } 
}); 
+0

この構文を説明できます:' const {checkbox1、checkbox2、checkbox3} = this.state; ' –

+0

onChange propの名前付き関数から無名関数を返すのは、 onChange propで匿名関数を直接使用するのと同じガーベジコレクションのパフォーマンスの問題? @ JoshBroadhurst。 –

+1

確かに、私はそれを言及すべきでした。これはオブジェクトの場合、[ES6 destructuring](http://exploringjs.com/es6/ch_destructuring.html#sec_overview-destructuring)です。 '' this.state''はいくつかのプロパティを含むオブジェクトです。引用した行で、checkbox1、checkbox2、checkbox3の名前と一致するプロパティを選択します。これらは、スコープ内の変数として使用できます。 'const checkbox1 = this.state.checkbox1;と書いたのと同じです。 const checkbox2 = this.state.checkbox2'など。 – jonahe