React小ネタ集 - stateでコンポーネントを複製, forEachで繰り返しrenderする
趣旨
同じようなcomponentをn個レンダリングしたい & 個々の細部はちょっとだけ変えたいという時に使える小ネタ。開発中に使えると思ったことをメモした。
作ったもの
https://codesandbox.io/s/qkvv35mn26
labelとテキストボックスがひとまとまりになった子コンポーネントを生成して、「挨拶する」ボタンをクリックすると個々の入力内容をアラートで表示するだけのシンプルなやつ。React-Bootstrapで簡単にスタイル付けもしている。
TL;DR
- state.languageに新たな要素を追加すれば勝手にrenderされるコンポーネントが増える。
- 合わせてshowFieldとinputTextにも要素を追加すれば何ヶ国語でも挨拶できるよ
- codesandbox上で自由に試して見てください
コンポーネントの構造
- App (親コンポーネント)
- MessageBox (子コンポーネント)
stateで制御しているもの
showField (Array)
- 各コンポーネントのうち、テキストエリアの表示状態を管理。
- 青文字のリンクをクリックするとハンドラが表示状態をトグルしてくれる。
language (Array)
- [言語コード, 言語名]が組みになった要素を格納した配列。
inputText (Object)
- 各テキストエリアの入力内容
各メソッドについて
showText
App.js
showText(e, langCode) {
let greeting = e.target.value;
if (this.state.inputText !== "") {
this.setState({
inputText: Object.assign({}, this.state.inputText, {
[langCode]: greeting
}),
})
}
}
- App (親コンポーネント)
- MessageBox (子コンポーネント)
stateで制御しているもの
showField (Array)
- 各コンポーネントのうち、テキストエリアの表示状態を管理。
- 青文字のリンクをクリックするとハンドラが表示状態をトグルしてくれる。
language (Array)
- [言語コード, 言語名]が組みになった要素を格納した配列。
inputText (Object)
- 各テキストエリアの入力内容
各メソッドについて
showText
App.js
showText(e, langCode) {
let greeting = e.target.value;
if (this.state.inputText !== "") {
this.setState({
inputText: Object.assign({}, this.state.inputText, {
[langCode]: greeting
}),
})
}
}
showText
showText(e, langCode) {
let greeting = e.target.value;
if (this.state.inputText !== "") {
this.setState({
inputText: Object.assign({}, this.state.inputText, {
[langCode]: greeting
}),
})
}
}
テキストエリアの入力内容に変更が起こると発火する。
入力したテキストをstateに格納してそのまま反映しているが、this.state.inputText
は各言語コードがキーとなっているのでそれを上書きしないよう、引数でイベントと言語コードを同時に受け取っている。Object.assign
の第二引数では既存のstateを受け取り、各言語コードをキーとして入力内容と合成し再びオブジェクトに結合してsetStateしている。
Object.assign()はReduxでもよく使われるが、素のReactでもこういった場面で使える。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
ちなみに普段通りにsetStateしようとすると一番新たに入力した言語のテキストしかstateにセットされなくなるので注意。
this.setState({inputText: {[langCode]: greeting}}),
handleTextField
handleTextField(e, number) {
e.preventDefault();
let showFieldState = this.state.showField;
showFieldState[number] = !this.state.showField[number];
this.setState({ showField: showFieldState });
}
「○○語で挨拶しましょう」というリンクをクリックすると発火する。
各コンポーネントはthis.state.showField
の配列で表示状態を管理しているので、n番目のコンポーネントの状態だけをトグルするように記述している。
render
render() {
const boxes = []
this.state.language.forEach((value, index) => {
boxes.push(<MessageBox
props= { this.state }
showText= { this.showText }
handler= { this.handleTextField }
key= { index }
showNum= { index } />)
})
Array.forEach()を使えばlanguageに入っている要素数だけコンポーネントをrenderできる。
ただ、return()句のなかでやろうとすると即時関数でラップしたりする必要があり、色々と面倒なので、returnの前で空配列を定義 -> forEachでコンポーネントを詰め詰め という手順でやっておいた方がラク。
keyに配列の添字を渡してやらないと各コンポーネントを識別できなくなりWarningが出るので注意。
showNumにも同じく配列の添字を渡してやることでthis.state.languageの内容を子コンポーネント側で読み取って反映させられる。
Author And Source
この問題について(React小ネタ集 - stateでコンポーネントを複製, forEachで繰り返しrenderする), 我々は、より多くの情報をここで見つけました https://qiita.com/takf-jp/items/1b30c8e1bdd9dd448615著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .