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

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

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

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

React.js

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

Q&A

0回答

1243閲覧

Reactの画面遷移を繰り返すとエラーが出る

shake4

総合スコア0

TypeScript

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

React.js

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

0グッド

0クリップ

投稿2021/06/01 15:55

前提・実現したいこと

React、typescriptで開発を行なっています。
2つの画面の作成まで完了しているので画面のRouteを使って画面の行き来ができるようにしたいです。

発生している問題・エラーメッセージ

npm startで外面の表示、その後のページ遷移まではできましたが、ホームに戻るを押すと、次のようなエラーが出ます。

covid/Cards/Cards.tsx

TypeError: Cannot read property 'length' of undefined 23 | <Typography variant="h5"> 24 | <CountUp 25 | start={0} > 26 | end={daily[daily.length - 1].Confirmed} | ^ 27 | duration={1.5} 28 | separator="," 29 | />

該当のソースコード

covid/Cards/Cards.tsx

import React from 'react'; import styles from "./Cards.module.css"; import CountUp from "react-countup"; import { Card, CardContent, Typography, Grid } from "@material-ui/core"; import { GiHastyGrave } from "react-icons/gi"; import { MdLocalHospital } from "react-icons/md"; import { AiFillLike } from "react-icons/ai"; import { useSelector } from "react-redux"; import { selectDaily } from "../covidSlice"; const Cards: React.FC = () => { const daily = useSelector(selectDaily); return ( <div className={styles.container}> <Grid container spacing={1} justify="center"> <Grid item xs={12} md={3} component={Card} className={styles.infected}> <CardContent> <Typography color="textSecondary" gutterBottom> <MdLocalHospital/> 感染者数 </Typography> <Typography variant="h5"> <CountUp start={0} end={daily[daily.length - 1].Confirmed} duration={1.5} separator="," /> </Typography> </CardContent> </Grid>      一部省略 </Grid> </div> ) }

/covid/covidSlice.ts

import { RootState } from './../../app/store'; import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; import axios from "axios"; import dataDaily from "./apiDataDaily.json"; const apiUrl = "https://api.covid19api.com/total/country"; type DATADAILY = typeof dataDaily; type covidState = { daily: DATADAILY; country: string; }; const initialState: covidState = { daily: dataDaily, country: "Japan", }; export const fetchAsyncGetDaily = createAsyncThunk( "covid/getDaily", async (country: string) => { const { data } = await axios.get<DATADAILY>(`${apiUrl}/${country}`); return {data: data, country: country} } ); const covidSlice = createSlice({ name: "covid", initialState: initialState, reducers: {}, extraReducers: (builder) => { builder.addCase(fetchAsyncGetDaily.fulfilled, (state, action) => { return { ...state, daily: action.payload.data, country: action.payload.country }; }); }, }); export const selectDaily = (state: RootState) => state.covid.daily; export const selectCountry = (state: RootState) => state.covid.country; export default covidSlice.reducer;

/covid/DashBoard/DashBoard.tsx

import React, { useEffect } from 'react'; import { makeStyles } from "@material-ui/core/styles"; import { AppBar, Toolbar, Typography, Container, Grid } from "@material-ui/core"; import styles from "./DashBoard.module.css"; import { useDispatch } from "react-redux"; import { fetchAsyncGetDaily } from "../covidSlice"; import SwitchCountry from '../SwitchCountry/SwitchCountry'; import Cards from '../Cards/Cards'; import Chart from '../Chart/Chart'; import PieChart from '../PieChart/PieChart'; import { Link } from 'react-router-dom'; const useStyles = makeStyles((theme) => ({ title: { flexGrow: 1, }, content: { marginTop: 85, }, bar: { background: "#38669d" } })); const DashBoard:React.FC = () => { const classes = useStyles(); const dispatch = useDispatch(); 一部省略 useEffect(() => { dispatch(fetchAsyncGetDaily("japan")); }, [dispatch]); return ( <div> 一部省略 <Container className={classes.content}> <div className={styles.container}> <SwitchCountry /> </div> <Grid container spacing={3}> <Grid item xs={12} md={12}> <Cards /> </Grid> <Grid item xs={12} md={7}> <Chart /> </Grid> <Grid item xs={12} md={5}> <PieChart /> </Grid> </Grid> </Container> <Link to="/linechart">押して</Link> </div> ); }; export default DashBoard

app/store.ts

import { configureStore, ThunkAction, Action } from '@reduxjs/toolkit'; import covidReducer from '../features/covid/covidSlice'; import CovidReducer from '../features/covid-linechart/covidSlice'; export const store = configureStore({ reducer: { covid: covidReducer, Covid: CovidReducer }, }); export type AppDispatch = typeof store.dispatch; export type RootState = ReturnType<typeof store.getState>; export type AppThunk<ReturnType = void> = ThunkAction< ReturnType, RootState, unknown, Action<string> >;

App.tsx

import React from 'react'; import { BrowserRouter, Route, Switch} from 'react-router-dom'; import LineDashBoard from './features/covid-linechart/DashBoard/DashBoard'; import DashBoard from './features/covid/DashBoard/DashBoard'; function App() { return ( <BrowserRouter> <Switch> <Route exact path="(/)?" component={DashBoard} /> <Route exact path="/linechart" component={LineDashBoard} /> </Switch> </BrowserRouter> ) } export default App;

試したこと

Cards.tsxのdailyが取得できていないことがわかったのでその原因を調査しましたが原因を特定することができませんでした。

補足情報(FW/ツールのバージョンなど)

package.json

{ "name": "dashboard", "version": "0.1.0", "private": true, "dependencies": { "@material-ui/core": "^4.11.4", "@reduxjs/toolkit": "^1.5.1", "@testing-library/jest-dom": "^4.2.4", "@testing-library/react": "^9.5.0", "@testing-library/user-event": "^7.2.1", "@types/jest": "^24.9.1", "@types/node": "^12.20.13", "@types/react": "^16.14.8", "@types/react-dom": "^16.9.13", "@types/react-redux": "^7.1.16", "axios": "^0.21.1", "chart.js": "^2.9.3", "connected-react-router": "^6.9.1", "history": "^4.10.1", "react": "^17.0.2", "react-chartjs-2": "^2.9.0", "react-countup": "^4.3.3", "react-dom": "^17.0.2", "react-icons": "^4.2.0", "react-redux": "^7.2.4", "react-router": "^5.2.0", "react-router-dom": "^5.2.0", "react-scripts": "4.0.3", "typescript": "~4.1.5" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject" }, "eslintConfig": { "extends": "react-app" }, "browserslist": { "production": [ ">0.2%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] }, "devDependencies": { "@types/react-router": "^5.1.14", "@types/react-router-dom": "^5.1.7" } }

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

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

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

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

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

hoshi-takanori

2021/06/01 18:04

covidSlice.tsx の daily がどこかで undefined になってるんでしょうけど、原因はよくわからないですね。画面遷移を繰り返すうちに country がおかしな値になって API の取得に失敗するとか? いずれにせよ、アプリ全体を動かしてデバッグしないとなんとも言えない気がします。 (あと、store のキーが covid と Covid なのは非常に紛らわしいというか…。)
shake4

2021/06/02 03:01

なるほど、、。 紛らわしいのは申し訳ありません。 アプリ全体のコードを載せたほうがわかりやすいでしょうか?
hoshi-takanori

2021/06/02 05:36

紛らわしいのは、個人開発で書いてる本人がちゃんと区別できてるならいいんですけどね。redux toolkit ならそれを区別する必要がある場所も限られますし…。 コードは、ここの質問文は文字制限があるようなので、たぶん全体は貼れないと思います。github などに上げてくれたら試しに動かすくらいはします (が、本格的にデバッグするとはお約束できません)。
hoshi-takanori

2021/06/02 19:45 編集

github 見ました。綺麗なアプリですね。 問題は src/features/covid-linechart/covidSlice.ts で、createSlice の引数 name は store のキーに合わせて Covid にする必要があります。さらに createAsyncThunk の最初の引数はたぶんアプリ全体でユニークにする必要があるので、習慣的にスライス名と同じものを使う (つまり covid/〜 じゃなくて Covid/〜 ですが、やはり紛らわしいので全体的に covidLinechart とかに変えた方が良のでは…) のが一般的かと思います。
shake4

2021/06/03 14:11

covid-linechart/covidSlice.tsのcreateSliceの引数をcovidLinechartに変更したところ、エラーが出なくなりました。 本当にありがとうございました。 (紛らわしかったのでフォルダ名や関数名も合わせて変更することにしました。)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問