質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.35%
TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

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

Q&A

解決済

2回答

2994閲覧

JavaScriptで有効なmap関数がTypeScriptで認識されない原因は?

Sean2014

総合スコア59

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

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

0グッド

0クリップ

投稿2020/06/14 14:03

編集2020/06/14 17:31

現在、ReactとTypeScriptの組み合わせでフロントエンドの実装をしようとしています。
今やろうとしている事の概要としては、バックエンドで処理された"word"をaxiosのgetで取得して配列に格納し、それをフロントエンドページで表示するという比較的シンプルな内容です。バックエンドの部分が正常に処理される事はPostmanで確認しておきました。

ReactとTypeScriptの組み合わせのチュートリアルで、自分のやりたい事に該当する内容のものがなかなか見当たらなかったのでReact+JavaScriptのチュートリアルを見ながら進めているのですが、チュートリアルでは問題なく実装できている部分が自分のTypeScriptではエラーになってしまいます。それがタイトルにもあるmap関数の部分です。チュートリアルでは問題ないのに、僕の場合は
TypeError: this.state.wordsData.map is not a functionというエラーが出てきてしまいます。

下記がコードです。

import React from 'react'; import axios from 'axios' import Word from '../interfaces/Word.interface'; class Home extends React.Component{ state = { wordsData:new Array<Word>() } componentWillMount(){ axios.get('http://localhost:8080/pictionarizerservices/api/words') .then(res => { const data = res.data; console.log("The content of res: "); console.log(res); this.setState({ wordsData:{ id: data.id, ownLangWordName: data.ownLangWordName, targetLangWordName: data.targetLangWordName, ownLangExSentence: data.ownLangExSentence, targetLangExSentence: data.targetLangExSentence, createdDate: data.createdDate } }) }) } render(){ return( <div> <h2>Words:</h2> <table> <thead> <tr> <th>ID</th> <th>Word (OL)</th> <th>Word (TL)</th> <th>Sentence (OL)</th> <th>Sentence (TL)</th> <th>Created Date</th> </tr> </thead> <tbody> {this.state.wordsData.map(singleWord=> <RowCreator id={singleWord.id} ownLangWordName={singleWord.ownLangWordName} targetLangWordName={singleWord.targetLangWordName} ownLangExSentence={singleWord.ownLangExSentence} targetLangExSentence={singleWord.targetLangExSentence} createdDate={singleWord.createdDate} />)} </tbody> </table> </div> ) } } class RowCreator extends React.Component<Word>{ render(){ let word = this.props; return( <tr> <td>{word.id}</td> <td>{word.ownLangWordName}</td> <td>{word.targetLangWordName}</td> <td>{word.ownLangExSentence}</td> <td>{word.targetLangExSentence}</td> <td>{word.createdDate}</td> </tr> ) } } export default Home;

TypeScriptのSyntaxに合わせるためにチュートリアルの部分と変えた所といえば、

state = { patientData:[] }

state = { wordsData:new Array<Word>() }

に、それから

class RowCreator extends React.Component{ ...

class RowCreator extends React.Component<Word>{ ...

にしたぐらいです。

僕がこれまで自分で勉強したり調べたりして現時点でわかっているのは、TypeScriptはJavaScriptの厳密なスーパーセットであり、JavaScriptで有効なコードはTypeScriptでも全て有効になるはずだという事です。また、TypeScriptはVisual Studio Codeでならコードを書いている時点で何か間違いがあればプログラムを実行する前からエラーがマークアップされて表示されるのですぐに間違いに気づけるとも聞いているのですが、全部エラーのマークアップが消えた後でRun timeでこのようなエラーが出てしまう理由がよくわかりません。

TypeScriptで

<tbody> {this.state.wordsData.map(singleWord=> <RowCreator id={singleWord.id} ownLangWordName={singleWord.ownLangWordName} targetLangWordName={singleWord.targetLangWordName} ownLangExSentence={singleWord.ownLangExSentence} targetLangExSentence={singleWord.targetLangExSentence} createdDate={singleWord.createdDate} />)} </tbody>

の部分を機能させるにはどうすればよいのでしょうか?

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

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

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

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

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

guest

回答2

0

ベストアンサー

こんにちは

TypeError: this.state.wordsData.map is not a function

というエラーが発生する原因は、axios によるGETが成功したときの、以下の部分

typescript

1this.setState({ 2 wordsData: { 3 id: data.id, 4 ownLangWordName: data.ownLangWordName, 5 targetLangWordName: data.targetLangWordName, 6 ownLangExSentence: data.ownLangExSentence, 7 targetLangExSentence: data.targetLangExSentence, 8 createdDate: data.createdDate 9 } 10})

で、statewordsDataプロパティに、配列ではなくオブジェクト

typescript

1{ 2 id: data.id, 3・・・ 4 createdDate: data.createdDate 5}

を setState してしまっていることと思われます。上記のsetStateによって、this.state.wordsData にオブジェクトを入れてしまうと、オブジェクトには map というメソッドはないので、render で返すJSX の中にある

JSX

1{this.state.wordsData.map(singleWord=> ・・・

で、this.state.wordsData.map is not a function というエラーになります。

修正方法としては、GETで返されたレスポンスから得られた配列を this.state.wordsData に setState するように、見直されることをお勧めします。

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

投稿2020/06/14 14:29

編集2020/06/14 17:02
jun68ykt

総合スコア9058

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

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

Sean2014

2020/06/14 17:34

ありがとうございます。アドバイスに沿って、先ほど自分で投稿した回答のようにしてみたらエラーが消えました。
jun68ykt

2020/06/14 17:37

どういたしまして???? 問題が解決したようで、よかったです????
guest

0

下記のように修正したらエラーが消えました。

this.setState({ wordsData:{ id: data.id, ownLangWordName: data.ownLangWordName, targetLangWordName: data.targetLangWordName, ownLangExSentence: data.ownLangExSentence, targetLangExSentence: data.targetLangExSentence, createdDate: data.createdDate } })

↓↓

this.setState({ wordsData:[{ id: data.id, ownLangWordName: data.ownLangWordName, targetLangWordName: data.targetLangWordName, ownLangExSentence: data.ownLangExSentence, targetLangExSentence: data.targetLangExSentence, createdDate: data.createdDate }] })

投稿2020/06/14 17:33

Sean2014

総合スコア59

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問