前提・実現したいこと
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" } }
あなたの回答
tips
プレビュー