Skip to content

Commit 7cefc77

Browse files
authored
Merge pull request #1 from cwen0/feat/interval-update-data
feat: add dumb fetch data logic with time interval
2 parents 0c4f2f5 + 4e4de2a commit 7cefc77

File tree

3 files changed

+75
-33
lines changed

3 files changed

+75
-33
lines changed

web/src/App.tsx

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
1-
import React, { Dispatch, SetStateAction, useState } from 'react';
2-
import styled, { ThemeProvider } from 'styled-components';
3-
import { Point } from 'react-simple-maps';
4-
import Banner from './components/Banner';
5-
import ChartContainer from './components/ChartContainer';
6-
import TrafficChart from './components/TrafficChart';
7-
8-
import { data } from './data';
1+
import React, { Dispatch, SetStateAction } from 'react'
2+
import styled, { ThemeProvider } from 'styled-components'
3+
import { Point } from 'react-simple-maps'
4+
import Banner from './components/Banner'
5+
import TrafficChartContainer from './components/ChartContainer'
96

107
export interface IAppState {
11-
selectedPoint: Point;
12-
setSelectedPoint: Dispatch<SetStateAction<Point>>;
8+
selectedPoint: Point
9+
setSelectedPoint: Dispatch<SetStateAction<Point>>
1310
}
1411

1512
const theme = {
@@ -25,47 +22,42 @@ const theme = {
2522
'#E67921',
2623
'#A62D4E'
2724
]
28-
};
25+
}
2926

3027
const AppStyles = styled.div`
3128
display: flex;
3229
flex-direction: column;
3330
text-align: center;
3431
height: 100%;
3532
margin-bottom: 20px;
36-
`;
33+
`
3734
const BodyStyles = styled.div`
3835
width: 95%;
3936
margin-left: auto;
4037
margin-right: auto;
41-
`;
38+
`
4239

4340
const Row = styled.div`
4441
margin-top: 20px;
4542
width: 100%;
4643
display: flex;
4744
flex-direction: row;
4845
justify-content: space-between;
49-
`;
46+
`
5047

5148
const App: React.FC = () => {
52-
// get the data coressponding to the selected point on the map
53-
const location = data;
54-
5549
return (
5650
<ThemeProvider theme={theme}>
5751
<AppStyles className="App">
5852
<Banner />
5953
<BodyStyles className="body">
6054
<Row>
61-
<ChartContainer title="Ping">
62-
<TrafficChart data={location.traffic}></TrafficChart>
63-
</ChartContainer>
55+
<TrafficChartContainer title="Ping" />
6456
</Row>
6557
</BodyStyles>
6658
</AppStyles>
6759
</ThemeProvider>
68-
);
69-
};
60+
)
61+
}
7062

71-
export default App;
63+
export default App
Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
1-
import React from 'react';
2-
import styled from 'styled-components';
1+
import React, { useState } from 'react'
2+
import styled from 'styled-components'
3+
4+
import TrafficChart from './TrafficChart'
5+
6+
import { useInterval } from '../utils/useInterval'
7+
import { data, ITrafficData } from '../data'
38

49
interface IChartProps {
5-
title: string;
10+
title: string
611
}
712

813
const ChartContainerStyles = styled.div`
@@ -14,21 +19,33 @@ const ChartContainerStyles = styled.div`
1419
flex-direction: column;
1520
width: 30%;
1621
height: 400px;
17-
`;
22+
`
1823
const ChartTitleStyles = styled.h2`
24+
width: 100%;
1925
padding: 0;
2026
font-size: 14px;
2127
align-self: flex-start;
22-
`;
28+
text-align: center;
29+
`
2330

2431
const ChartContainer: React.FC<IChartProps> = props => {
25-
const { title } = props;
32+
const { title } = props
33+
const [traffic, setTraffic] = useState<ITrafficData[]>([])
34+
35+
const fetchData = () => {
36+
console.log('on fetch data', new Date())
37+
// TODO: use real fetch data API, and update response data with setTraffic Hook
38+
setTraffic(data.traffic)
39+
}
40+
41+
useInterval(fetchData, 10 * 1000, true)
42+
2643
return (
2744
<ChartContainerStyles>
2845
<ChartTitleStyles>{title}</ChartTitleStyles>
29-
{props.children}
46+
<TrafficChart data={traffic} />
3047
</ChartContainerStyles>
31-
);
32-
};
48+
)
49+
}
3350

34-
export default ChartContainer;
51+
export default ChartContainer

web/src/utils/useInterval.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// useInterval Custom Hook
2+
// Making setInterval Declarative with React Hooks
3+
4+
import { useEffect, useRef } from 'react'
5+
6+
const noop = () => {} // keep typescript happy
7+
export const useInterval = (
8+
callback: () => void,
9+
delay: number | null,
10+
immediate?: boolean // called when mounted if true
11+
) => {
12+
const savedCallback = useRef(noop)
13+
14+
// Remember the latest function.
15+
useEffect(() => {
16+
savedCallback.current = callback
17+
})
18+
19+
// Execute callback if immediate is set.
20+
useEffect(() => {
21+
if (!immediate) return
22+
savedCallback.current()
23+
}, [immediate])
24+
25+
// Set up the interval.
26+
useEffect(() => {
27+
if (delay === null) return undefined
28+
29+
const tick = () => savedCallback.current()
30+
const id = setInterval(tick, delay)
31+
return () => clearInterval(id)
32+
}, [delay])
33+
}

0 commit comments

Comments
 (0)