REST countries API [react, react router v6, redux, asyncThunks]

Solution retrospective
This is my first project where I work with external REST API resources. For this task I decided to use Redux'es createAsyncThunk because it gives you an opportunity to easily handle different states the application is in at the moment of hooking from external API. Working with React components again I found it quite disastrous to make styles for every component in a separate file and eventually I always got lost. So, I need to find any solution to alleviate my struggles during such projects. Any code review would be amazing. Thank you!
Please log in to post a comment
Log in with GitHubCommunity feedback
- @j0sephh123
- When you need to use logic in react components, but don't need to return JSX, as is in src/components/ScrollToTop/ScrollToTop.jsx - create a custom hook
- Haven't used
unwrap
forcreateAsyncThunk
, so thanks for introducing that to me :) src/routes/app/App.jsx
useEffect
seems to be missing dependencies. I suggest that you setup eslint and the hooks plugin - https://www.npmjs.com/package/eslint-plugin-react-hooks It is pain to setup, but will warn you for missing or incorrect dependencies for useEffect, useMemo, useCallback and so on.- Regarding your struggle with styles - you can look into SCSS modules, Tailwind or https://stitches.dev/. Really depends on your style. Personally I'm using SCSS modules at work and working on a project here with stitches and it is very nice - very convenient for a global theme. A bit hard to get into.
src/components/Header/Header.jsx
- you can create enum for themes, instead of using raw stringssrc/components/InputElement/InputElement.jsx
-'await' has no effect on the type of this expression
this is for setTimeout. Also, you can use the shorthand syntax for this:onChange={handleInput}
Also shorthand for this:{countryName && <div className="close" onClick={handleErase}></div>}
It is good that you have 1sec debounce after typing to avoid sending fast requests. You can also use https://usehooks.com/useDebounce/ or extract your own logic into a custom hook for reusability. (not that it is needed here)src/features/regions/Regions.jsx
-hidden={countryRegion === '' ? true : false}
can be simplyhidden={countryRegion === ''}
- same for
selected={countryRegion === region ? true : false}
- what is
firstRender
used for? It doesn't seem to do anything, you just set it in the useEffect. src/features/countries/Countries.jsx
InhandleScroll
avoid lenghty statements inside if. Create a variable and use it inside if. I will try to provide an idea. Note that there is a high probability that this syntax may not be working outside of the box, it is just to illustrate what I have in mind:
// Countries const Countries = () => { ... const isLoading = useSelector(selectCountriesIsLoading); useHandleScroll(isLoading, () => dispatch( loadCountries({ countryName: null, countryRegion: null, scroll: true }) ) ); ...
And a new hook file
//src/features/countries/useHandleScroll.js export default function useHandleScroll(isLoading, callback) { const handleScroll = () => { const ourVariableName = window.innerHeight + Math.ceil(window.pageYOffset) >= document.body.offsetHeight && !isLoading; if (ourVariableName) { callback(); } }; useEffect(() => { window.addEventListener("scroll", handleScroll); return () => window.removeEventListener("scroll", handleScroll); }, [isLoading]); }
Marked as helpful
Join our Discord community
Join thousands of Frontend Mentor community members taking the challenges, sharing resources, helping each other, and chatting about all things front-end!
Join our Discord