当サイトは、アフィリエイト広告を利用しています
当ブログはReactのフレームワークのGatsbyで作成している。
Reactで使われるJSX記法についてブログ作成時、独学で学んだ中で
要点だと思ったことを忘備録として残す
その前にReactの画面描写の仕組みから知りたいという方は
下記記事で描写の仕組みをまとめています。
イメージ的には、下記の return()の中が jsx記法 のイメージ。
{}の中ではjs部分(returnより上)で定義した変数や関数を使用することができる。
const HogeButton = ({ primary, label }) => {return (<button>{primary? <div className='primaryButtonInner'>{label}</div>: <div className='normalButtonInner'>{label}</div>}</button>)}
一番外側の親要素は一つでないといけない。 ※エラーになる
const HogeButton = ({ primary, label }) => {return (<button>{primary? <div className='primaryButtonInner'>{label}</div>: <div className='normalButtonInner'>{label}</div>}</button>)}
jsx内でネストして即時関数を書いた場合なども返却用の配列などを使用して
一つの親タグ内に収まるようにする必要あり
export default function App() {let song = ["すべてはFになる", "封印再度", "詩的私的ジャック"];return (<div className="App"><h1>Hello CodeSandbox</h1>{(() => {//jsx内で即時関数を使う場合//返却用配列const items = [];song.forEach(element => {items.push(<div>{element}</div>)});//戻り値は一つのタグ内の入れるreturn <div>{items}</div>;})()}</div>);}
JSX内で変数定義や関数定義をすることはできない。 関数については即時関数であれば使うことができる
Reactが採用しているJSXではif文はかけない。 JSX内でif文を書きたい場合は4通りの方法がある。
JSX内の即時関数内でIF文を書く
export const HogeButton = ({ title,flg }) => {return (<section className="h2_elem">{/* 即時関数(returnは必須) */}{(() => {if ( flg === "1" ) {return <p>hoge1</p>} else {return <p>hoge2</p>}})()}</section>)}export default function App() {return (<div className="App"><HogeButton title={"bottun"} flg={"0"}/></div>);}
一つならいいかもしれないが、大分見づらい...
あまり使わない方が良さそう。
JS部分に関数定義しておき、JSX内で呼び出す方式。
// 関数を定義const hogeFunc = (flg) => {if (flg === "1") {return <p>hoge1</p>;} else {return <p>hoge2</p>;}};const HogeButton = ({ flg }) => {return (//<section className="h2_elem">{/* 外部で定義した関数を呼ぶ */}{hogeFunc(flg)}</section>);};export default function App() {return (<div className="App"><HogeButton flg={"1"} /></div>);}
「&&」を使って条件付きレンダーで書く。
一番よく見かけるパターンなので基本はこのパターンを使うでいいと思う。
export const HogeButton = ({ flg }) => {return (//<section className="h2_elem">{/*条件付きレンダー */}{flg === "1" && <p>hoge1</p>}{flg !== "1" && <p>hoge2</p>}</section>);};export default function App() {return (<div className="App"><HogeButton title={"bottun"} flg={"1"} /></div>);}
JSX内では三項演算子を使える。
export const HogeButton = ({ flg }) => {return (//<section className="h2_elem">{/*三項演算子 */}{flg === "1" ? <p>hoge1</p> : <p>hoge2</p>}</section>);};export default function App() {return (<div className="App"><HogeButton title={"bottun"} flg={"2"} /></div>);}
if文と同様にJSX内でfor文を普通に書くとエラーになる。
JSX内でfor文を使うには下記の4つの方がある。
if文と同様にJSX内に直接書きたい場合は即時関数を使う必要がある。
//即時関数(()=> {//処理})();
実際に書いてみる
export default function App() {let song = ["すべてはFになる", "封印再度", "詩的私的ジャック"];return (<div className="App"><h1>Hello CodeSandbox</h1>{(() => {//forを使うパターン//返却用配列const items = [];for (let i = 0; i < 5; i++) {items.push(<div>{song[i]}</div>);}return <div>{items}</div>;// forEachを使うパターン// //返却用配列// const items = [];// song.forEach(element => {// items.push(<div>{element}</div>)// });// return <div>{items}</div>;})()}</div>);}
返却用配列を使わないダメなパターン
export default function App() {let song = ["すべてはFになる", "封印再度", "詩的私的ジャック"];return (<div className="App"><h1>Hello CodeSandbox</h1>{(() => {//forを使うfor (let i = 0; i < 5; i++) {return <div>{song[i]}</div>;}// forEachを使う// song.forEach(element => {// return (<div>{element}</div>)// });})()}</div>);}
外部で関数を定義し、JSX内で呼ぶこともできる。 ただし外部関数でも戻り値は一つの親タグ内に収める必要あり。
//外部で関数を定義export const novel = (novels) => {//表示用配列const novelsArray = [];novels.forEach((novel) => {novelsArray.push(<div>{novel}</div>);});return <div>{novelsArray}</div>;};export default function App() {let novels = ["すべてはFになる", "封印再度", "詩的私的ジャック"];return (<div className="App"><h1>Hello CodeSandbox</h1>{/* 外部で定義した関数を呼ぶ */}{novel(novels)}</div>);}
reactで一番見る形で個人的には一番シンプルでわかりやすい。
特に理由がない場合はこの書き方にする。
export default function App() {let novels = ["すべてはFになる", "封印再度", "詩的私的ジャック"];return (<div className="App"><h1>Hello CodeSandbox</h1>{/* mapを使う */}{novels.map(novel=><div>{novel}</div>)}</div>);}
filterとmapを使用する場合は下記のようになる。
export default function App() {let novels = ["すべてはFになる", "封印再度", "詩的私的ジャック"];return (<div className="App"><h1>Hello CodeSandbox</h1>{/* mapやfilter使う */}{novels.filter((nov) => nov !== "封印再度").map((novel) => (<div>{novel}</div>))}</div>);}
テンプレート文字列を使って下記のように書くことができる
export default function App() {let novels = ["すべてはFになる", "封印再度", "詩的私的ジャック"];return (<div className="App"><h1>Hello CodeSandbox</h1>{novels.map((novel) => ({/*テンプレート文字列を使う */}<div>{`森博嗣:${novel}`}</div>))}</div>);}