引き続きReactの勉強をしていきたいと思います。
前回使ったボタンコンポーネントを利用しつつ、複数の要素を使用してボタン側と表示側を切り離してみたいと思います。
JSX,REACT,REACT DOMが既に入っているこちらのIDEを使って一緒に進めていくとやりやすいです。
https://jscomplete.com/playground
function Button(props) {
return (
<button onClick={props.onClickFunction}>
+1
</button>
);
}
function Display(props) {
return (
<div>{props.message}</div>
);
}
function App() {
const [counter, setCounter] = useState(0);
const incrementCounter = () => setCounter(counter+1);
return (
<div>
<Button onClickFunction={incrementCounter}/>
<Display message={counter}/>
</div>
);
}
ReactDOM.render(
<App />,
document.querySelector("body"),
);
前回のコードを引継ぎつつ入力するButton要素と出力するDisplay要素に分けていったのが上記のコードになります。
まずreturnするときに()がつく時があると思うのですが、これは複数行にして書きたい時に使用します。
長いものであると可読性が下がるので考えにくいですが2行めは下記のように書くこともできます。
return <button onClick={props.onClickFunction}>+1</button>
単純で短いものはインラインで書いても良いかと思うのですが、使い分けとして覚えておくのはありかと思います。
作成したそれぞれの要素はReactDOM.renderのなかに書き込んでいきます。
冒頭にあるコードでは
function A() {
return (
<div>aaaa</div>
);
}
function B() {
return (
<div>bbbb</div>
);
}
ReactDOM.render(
[<A />,<B />],
document.querySelector("body"),
);
一つ目に配列としてReactの要素をいれることができます。
レンダリングしている要素が動的に同じコンポーネントから取得されている場合に使える方法です。
function A() {
return (
<div>aaaa</div>
);
}
function B() {
return (
<div>bbbb</div>
);
}
ReactDOM.render(
<div>
<A />
<B />
</div>,
document.querySelector("body"),
);
もう一つの方法としては複数のReact要素をdivで囲い子要素とすることです。
こうすることで、個別の要素として参照できるので正しく表示されます。
function A() {
return (
<div>aaaa</div>
);
}
function B() {
return (
<div>bbbb</div>
);
}
ReactDOM.render(
<React.Fragment>
<A />
<B />
</React.Fragment>,
document.querySelector("body"),
);
ただ、divの親要素が不要な場合があると思います。その場合はReact.Fragmentを利用して子要素のみ表示できるようになります。
Vueではtemplate要素の直下にdivがないと行けない規則があったりするのでこれは便利ですね!
function A() {
return (
<div>aaaa</div>
);
}
function B() {
return (
<div>bbbb</div>
);
}
function C() {
return (
<>
<A />
<B />
</>
);
}
ReactDOM.render(
<C />,
document.querySelector("body"),
);
上記で説明したように個別に配置することもできまずが、Cコンポーネントの中にまとめてしまった方がきれいに収まります。
(因みにReact.Fragmentは<>にて省略が可能です。)
function A() {
const hoge = "aaaa";
return (
<div>{hoge}</div>
);
}
function B() {
return (
<div>bbbb</div>
);
}
このように指定された変数はコンポーネント内のみにしか使用できません。 どのようにするかというと
function A(props) {
return (
<div>{props.message}</div>
);
}
function B(props) {
return (
<div>{props.message}</div>
);
}
function C() {
const hoge = "aaaa";
return (
<>
<A message="hoge"/>
<B message="hoge"/>
</>
);
}
ReactDOM.render(
<C />,
document.querySelector("body"),
);
このように親要素へ変数を配置してあげる必要があります。 そうすることによって二つのコンポーネントで同じ変数を使えるようになります。
function A(props) {
return (
<div onClick={props.clickFunction}>{props.message}</div>
);
}
function B(props) {
return (
<div>{props.message}</div>
);
}
function C() {
const button = "おしてね";
const hoge = "aaaa";
const fuga = () => {console.log("aaa")};
return (
<>
<A message={button} clickFunction={fuga}/>
<B message={hoge}/>
</>
);
}
ReactDOM.render(
<C />,
document.querySelector("body"),
);
上記はAコンポーネントで表示した文言にクリックイベンをつけたものとなります。 関数は単なるJavascriptのオブジェクトとなるので、変数と同じような要領で関数を送ることも可能です。
Reactにて複数のコンポーネントがある状態でどのように値を受け渡すのかがなんとなく見えてきましたね。 実務でもjsフレームワークを使うとここら辺がややこしかったりするので、確実に抑えておきたいところです!