@@ -17,62 +17,62 @@ interface Color {
1717}
1818
1919function App ( ) : JSX . Element {
20- const isMounted = useRef ( false ) ;
2120 const [ loadPanelVisible , setLoadPanelVisible ] = useState < boolean > ( false ) ;
2221 const [ pageSize , setPageSize ] = useState < number > ( 5 ) ;
2322 const [ pageIndex , setPageIndex ] = useState < number > ( 3 ) ;
24- const [ colors , setColors ] = useState < Color [ ] > ( [ ] ) ;
2523 const [ visibleCards , setVisibleCards ] = useState < Color [ ] > ( [ ] ) ;
2624
27- const getVisibleCards = useCallback ( ( currentPageIndex : number , currentPageSize : number ) : void => {
28- const startIndex = ( currentPageIndex - 1 ) * currentPageSize ;
29- const endIndex = startIndex + currentPageSize ;
30- const pageColors = colors . slice ( startIndex , endIndex ) ;
31- setVisibleCards ( pageColors ) ;
32- setLoadPanelVisible ( false ) ;
33- } , [ colors , visibleCards ] ) ;
25+ const hexCodes = useRef < string [ ] > ( [ ] ) ;
26+ const colorsCache = useRef < Map < string , Color > > ( new Map ( ) ) ;
3427
35- const generateColors = useCallback ( async ( total : number ) : Promise < void > => {
36- setLoadPanelVisible ( true ) ;
37- const promises : Promise < Color | null > [ ] = [ ] ;
28+ useEffect ( ( ) => {
3829 for ( let i = 0 ; i < total ; i ++ ) {
39- const hex = getRandomPastelColor ( ) ;
40- promises . push ( fetchColorData ( hex ) ) ;
30+ hexCodes . current . push ( getRandomPastelColor ( ) ) ;
4131 }
32+ } , [ ] ) ;
33+
34+ const fetchColorsForPage = useCallback ( async ( ) : Promise < void > => {
35+ setLoadPanelVisible ( true ) ;
36+ const startIndex = ( pageIndex - 1 ) * pageSize ;
37+ const endIndex = startIndex + pageSize ;
38+ const hexSubset = hexCodes . current . slice ( startIndex , endIndex ) ;
39+
40+ const promises = hexSubset . map ( ( hex ) => {
41+ if ( colorsCache . current . has ( hex ) ) {
42+ return Promise . resolve ( colorsCache . current . get ( hex ) ) ;
43+ }
44+ return fetchColorData ( hex ) . then ( ( color ) => {
45+ if ( color ) {
46+ colorsCache . current . set ( hex , color ) ;
47+ }
48+ return color ;
49+ } ) ;
50+ } ) ;
4251
4352 try {
4453 const results = await Promise . all ( promises ) ;
4554 const filteredColors = results . filter ( ( color ) : color is Color => color !== null ) ;
46- setColors ( filteredColors ) ;
55+ setVisibleCards ( filteredColors ) ;
4756 } catch ( error ) {
48- console . error ( 'Error generating colors:' , error ) ;
57+ console . error ( 'Error fetching colors:' , error ) ;
58+ } finally {
59+ setLoadPanelVisible ( false ) ;
4960 }
50- } , [ total ] ) ;
61+ } , [ pageIndex , pageSize ] ) ;
5162
5263 const onPageIndexChange = useCallback ( ( value : number ) => {
5364 setPageIndex ( value ) ;
54- getVisibleCards ( value , pageSize ) ;
55- } , [ pageSize , getVisibleCards ] ) ;
65+ } , [ ] ) ;
5666
5767 const onPageSizeChange = useCallback ( ( value : number ) => {
5868 setPageSize ( value ) ;
59- getVisibleCards ( pageIndex , value ) ;
60- } , [ pageIndex , getVisibleCards ] ) ;
61-
62- useEffect ( ( ) => {
63- if ( ! isMounted . current ) {
64- isMounted . current = true ; // Mark as mounted
65- generateColors ( total ) . catch ( ( error ) => {
66- console . error ( 'Error initializing colors:' , error ) ;
67- } ) ;
68- }
6969 } , [ ] ) ;
7070
7171 useEffect ( ( ) => {
72- if ( colors . length > 0 ) {
73- getVisibleCards ( pageIndex , pageSize ) ;
74- }
75- } , [ colors ] ) ;
72+ fetchColorsForPage ( ) . catch ( ( error ) => {
73+ console . error ( 'Error updating visible cards:' , error ) ;
74+ } ) ;
75+ } , [ fetchColorsForPage ] ) ;
7676
7777 return (
7878 < div className = "main" >
@@ -94,8 +94,8 @@ function App(): JSX.Element {
9494 onPageSizeChange = { onPageSizeChange }
9595 />
9696 < div id = "cards" >
97- { visibleCards . map ( ( color ) => (
98- < div key = { color . name } >
97+ { visibleCards . map ( ( color , index ) => (
98+ < div key = { index } >
9999 < img src = { color . image } alt = { color . name } />
100100 </ div >
101101 ) ) }
0 commit comments