質問するログイン新規登録
React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

3回答

2911閲覧

React.jsで条件分岐を使って表示される内容を切り替える際のエラーについて。

moriman

総合スコア615

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2019/08/04 02:46

0

0

class PrintProbability extends React.Component { render(){ return( {(()=>{ if(!isNaN(this.props.probability)){ <div>{this.props.roletype}確率 :<br/> 1/{(this.props.probability).toFixed(1)}<hr/></div> }else{ <div>未入力です。</div> } })()} ) } }

Reactで確率を計算して表示するコンポーネントで、親コンポーネントから受け取った
this.props.probabilityがNaNの時とそうでない時で表示を切り替えたいです。
即時関数を使った上のコードで動かすと

babel.js:14449 Uncaught SyntaxError: Inline Babel script: Unexpected token (369:5) 367 | render(){ 368 | return( > 369 | {(()=>{ | ^ 370 | if(!isNaN(this.props.probability)){ 371 | <div>{this.props.roletype}確率 :<br/> 1/{(this.props.probability).toFixed(1)}<hr/></div> 372 | }else{ at Parser.pp$5.raise (babel.js:14449) at Parser.pp.unexpected (babel.js:11756) at Parser.pp$3.parseIdentifier (babel.js:14327)

上記のようなエラーが出ます。何が原因なのでしょうか。書き方のような気がするのですが。
条件分岐なしのコンポーネントの場合エラー無しで動くので、ここが原因だと思います。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

こんにちは

ご質問に挙げられているコードの検証用に、修正ふくめて、以下

に上げています。 initial commit では、ご質問に挙げられている PrintProbability をそのままコピペしたものをコミットしていますが、 App から何もpropsを渡さないで、

jsx

1<PrintProbability />

と書くと、確かにご質問にあるエラーが発生しました。

修正箇所ですが、ご質問に挙げられている PrintProbability の render() で return している中の即時関数に、最低限の修正をして動くものにするには、以下のようにします。

修正前

jsx

1class PrintProbability extends React.Component { 2 render(){ 3 return( 4 {(()=>{ 5 if(!isNaN(this.props.probability)){ 6 <div>{this.props.roletype}確率 :<br/> 1/{(this.props.probability).toFixed(1)}<hr/></div> 7 }else{ 8 <div>未入力です。</div> 9 } 10 })()} 11 ) 12 } 13}

修正後

jsx

1class PrintProbability extends React.Component { 2 render(){ 3 return( 4 (()=>{ 5 if(!isNaN(this.props.probability)){ 6 return <div>{this.props.roletype}確率 :<br/> 1/{(this.props.probability).toFixed(1)}<hr/></div> 7 }else{ 8 return <div>未入力です。</div> 9 } 10 })() 11 ) 12 } 13}

上記の修正に相当するコミットは以下です。

上記の修正により、とりあえずエラーは解消されて、 「未入力です。」が表示されるようになります。

補足としまして、上記のコミットに続く以下は、リファクタの一案です。

  • 以下の2点をリファクタ
    ・isNaNのときにエンプティステートを返す処理に三項演算子を使用
    ・propsからの値取得に分割代入を使用

以上、参考になれば幸いです。

追記

さらにつけ加えると、三項演算子も使うまでもなく、エンプティステートを表示する条件に合致したら、その場で render() から return させるというのも(私は)よく使います。

投稿2019/08/04 12:15

編集2019/08/05 00:49
jun68ykt

総合スコア9058

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hood

2019/08/04 12:40

即時関数でも返せるのですね・・・勉強になりました・・・私の回答も修正したいと思います。
jun68ykt

2019/08/04 13:05

コメントありがとうございます。 render の return 対象のJSXの中に即時関数を書くのは、コンポーネントを分割したり共通化するといった整理は後回しにして、とりあえず、要件を満たすロジックをとり急ぎ書いてしまいたいときに、私もときどきやります。
moriman

2019/08/06 00:42

回答ありがとうございます。まず頂いた修正後のコードでエラーなく動きました。 上記修正前に私が挙げたコードは速習リアクトという書籍のサンプルをまねして書きました。 確かにreturnはサンプルコードにも書いてあり、私の書き忘れでした。 それはわかるのですが、書籍のサンプルでは即時関数を中カッコ{}で囲んでいるんですよね。 これって書いたらダメなんでしょうか? 実際中カッコで囲んだらエラーが出て、はずすとエラーが出ないので不要なのですけど(笑) ぱっと見、中カッコあってもおかしくないような気もするんですが。
moriman

2019/08/06 00:47

というか、今見てて思ったんですが、returnで即時関数から返されるのはReact要素なので それは中カッコで囲む必要はない、囲むとおかしくなる、ということですか。 それなら確かにそうだ、とは思いました。
jun68ykt

2019/08/06 06:02

@morimanさん コメントありがとうございます。 > 実際中カッコで囲んだらエラーが出て、はずすとエラーが出ないので不要なのですけど(笑) > ぱっと見、中カッコあってもおかしくないような気もするんですが。 はい。そんな気もしますね。ですが、javascript の文法では、return 文の決まりとして以下 https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/return のように、 return の後に書けるのは式(expression)です。 ご質問に挙げられている、修正前のコードでは、即時関数の返り値を { ・・・ } でくくることによって、return で返そうとする対象が、式にならなくなってしまうので、文法エラーになります。
jun68ykt

2019/08/06 06:22

ご質問に挙げられている { } のある方がエラーになって、 { } がないとエラーにならないのは、次の簡単なサンプルでも確かめられます。単に 10 を返す関数 function f() { return 10; } は文法として正しく、 fを実行すると 10 を返しますが、 この 10 を { } でくくって function f() { return { 10 }; } と書くと文法エラー(SyntaxError)になります。
moriman

2019/08/07 08:57

そういうことなんですね。書籍のサンプルもjsxの途中で中カッコを使ってたので問題ない。returnの直下で中カッコで囲んでしまうとエラーになるんですね。 わかりやすい解答を頂きましてありがとうございました。
guest

0

returnが返すのはjsxなのであくまで即時関数である式は、返すことができないのだと思います。
->jun68yktさんの回答のように{}を外せば大丈夫なようです。またreturn文もつけるとのことでした。きちんと検証しないで申し訳なかったです。

以下編集済みコード


以下のようにReact.Fragmentの内部に閉じ込めてやればいいのではないでしょうか?

react

1 class PrintProbability extends React.Component { 2 render(){ 3 return( 4 <> 5 {(()=>{ 6 if(!isNaN(this.props.probability)){ 7 return <div>{this.props.roletype}確率 :<br/> 1/{(this.props.probability).toFixed(1)}<hr/></div> 8 }else{ 9 return <div>未入力です。</div> 10 } 11 })()} 12 </> 13 ) 14 } 15 }

<>はReact.Fragmentの省略です。

参考文献の「Arrow 関数でもOK」の部分を見て考えました。

投稿2019/08/04 03:28

編集2019/08/04 12:45
hood

総合スコア351

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

moriman

2019/08/06 00:43

回答ありがとうございました。
guest

0

functional componentならhoodさんの回答でも良いかもしれませんが、class componentなんだから関数部分を切り出してclass内に定義して(切り出して)、それを呼んでやる方法でも良いかと。

投稿2019/08/04 07:31

gentaro

総合スコア8947

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hood

2019/08/04 11:40

なるほど、確かにそちらのほうが見やすいかもしれませんね。
moriman

2019/08/06 00:43

回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.30%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問