現状
React.js(17.0.2)、TypeScript(4.2.4)で時計(Clock)Componentと電車情報を1分に1回00秒のときにAPIで取得するTrainTimeTableComponentをHooksで作っております。
以下、コードの主要部分のみ抜粋したものです。
tsx
1function TrainTimeTable() { 2 const [stationName, setStationName] = useState<string>(); 3 // 別のClockコンポーネントで毎秒timeを現在時刻に変更しています 4 const { time } = useSelector((state: any) => state.timer); 5 const now = DayJs(time); 6 7 useEffect(() => { 8 if (shouldRefetch()) { apiCall(); } 9 }, [now]); 10 11 const shouldRefetch = () => { 12 return !stationName || now.format("ss") === "00" 13 } 14 15 const apiCall = async () => { 16 // stationNameないとき(=最初のマウント時)と、秒が00のときに発火しています 17 console.log("FETCH Train TimeTable", now); 18 const response: any = await axios.get(EKISPART_API_BASE_URL, 19 { 20 params: { 21 key: process.env.EKISPART_API_KEY, 22 date: now.format("YYYYMMDD"), 23 } 24 }) 25 const data = response.data.ResultSet.TimeTable; 26 setStationName(data.Station.Name); 27 } 28 29 return ( 30 <h1 className="text-xl">{stationName}駅の運行情報</h1> 31 ); 32} 33 34export default TrainTimeTable;
timeの更新を行っているコード
tsx
1function Clock() { 2 const { time } = useSelector((state: any) => state.timer); 3 const dispatch = useDispatch(); 4 5 useEffect(() => { 6 const timerId = setInterval(() => dispatch(tick(DayJs().format('YYYY/MM/DD HH:mm:ss'))), 1000); 7 8 return () => clearInterval(timerId); 9 }); 10 const now = DayJs(time); 11 12 return ( 13 <p className="text-2xl text-thinGray">{now.format('YYYY/MM/DD')}</p> 14 ); 15};
redux-toolkitを使っているのですが、timeの更新が1秒に1度のみ動いていることは以consoleで確認できましたと思われます。以下がdispatchで動かした関数にしこんだログです。
action! 2021/05/02 18:53:10 TimerSlice.tsx:18 action! 2021/05/02 18:53:11 TimerSlice.tsx:18 action! 2021/05/02 18:53:12 TimerSlice.tsx:18 ...
課題
apiCall関数が、stationNameないとき(=最初のマウント時)と、秒が00のときに発火しています。
が、consoleをみると00秒のときに、複数回 console.log("FETCH Train TimeTable", now);
が走ってしまっています。
期待しているのは、00秒のときに1度だけ発火することです。
聞きたいこと
上記の課題である、なぜ複数回apiCallが走ってしまっているのかについて、原因と解消方法を知りたいです。
ご存じの方がいらっしゃればご教示いただけると幸いです。
あなたの回答
tips
プレビュー