Solution for a challenge from Devchallenges.io.
This application/site was created as a submission to a DevChallenges challenge. The challenge was to build an application to complete the given user stories. Note: The previous design document may be incomplete, as you need to find an archived version of the challenge as all legacy
challenges have had their documentation removed from DevChallenges.
- You can see at least 2 types of questions: a city is the capital of.. or a flag belong to country..
- You can select an answer
- You can see if answer is correct or incorrect
- When you answer correctly, you move on to the next question
- When you answer incorrectly, you see your results
- You can try again
- Implementation choice: grab all data once vs grabbing data after each correct submission.
- Since the game should end after a wrong answer, it may be best to refetch data after each correct answer.
- Are users going to play long enough to require more data than the initial download size?
- How many questions do you have to get correct in a row to surpass the initial download size?
- How long would users typically use such an app?
- You can waste users' bandwidth.
- Grabbing all the countries is ~ 146kb.
- Selecting all countries of a region is ~ 30kb.
- You can drastically cut that by filtering with fields (name,capital,flags).
- Selecting one country is ~ 1.5kb.
- 368ms for 4 parallel queries by name without filtering.
- Times can really vary, but with filtering each query should be 40-70ms at best and 100ms+ at worst.
- Since you need 4 answers, is it best to do a parallel query?
- Could use an answer array and function to get a random value to complete the query.
- Could make an array of all 250 countries and then grab 4 random values and then complete 4 queries with those values.
- The API does have some weird inconsistencies and creates edge cases you need to account for.
- Querying a name on the API can be problematic for countries with names longer than one word. May need to encode the space with
%20
and verify how the API named such countries. - Some countries may return an array for a field when most countries would have only a string - if country had a territory - etc.
- So I just removed certain problematic countries from the countries array.
- The fact that React Query documentation is minimal (on purpose) really made this more difficult to choose implementation details.
- useQueries may not be an ideal solution here. The amount of queries is not going to change, but I think it makes sense to batch code versus having 4 separate queries where you have to alias all returned properties. Stack Overflow mentioned this dilemma and the unclear implementation details in the docs.
- The poor documentation is why I went through a YouTube course on React Query.
- Seems like React Query makes more network requests than you would think. It is definitely over-eager in fetching data and I think that could be why passing variables to React Query can cause issues, i.e. infinite loops.
- The DevChallenges requirements bake in poor performance. Client-side rendering. You need multiple API calls for one question or a large api call. You possibly need a global state object for scoring.
- React 18 shows double all console logs in strict mode. I had trouble checking an useQueries error because the console logs were flooded.
- React 18 evaluates components twice.
useId
is not for adding keys to a list items insiderender
. I made that mistake in the Capital and Flag components.useId
is implemented with refs. See React Docs for more.useId
is really not useful, and I don't seeuseId
being used extensively.- There are problems when the flag image doesn't show up. User scores are lost on refresh. A user will just have to guess if there is no flag.
- To keep answer hidden, useQuery(
https://restcountries.com/v3.1/name/{answer}?fields=capital
) then evaluate the returned capital name to your answer - Extra request may not be necessary?
- I thought about not showing result screen if score was 0 and you got first question wrong -> just reload the page.
- I didn't consult the project requirements enough doing this - my primary goal was using React Query and getting it working.
- Design implies no start screen - ie load question on first load - but has end result page. With React Query, it would make more sense if there was a start and end screen - so you can set
enabled: false
. Otherwise, you might have to duplicate logic or send a parameter to flip the value of enabled. - Testing React Query is an involved process with limited information. This application might be easier to test since I used custom hooks. I have not seen how to test React Query without a custom hook wrapper.
- Steps to replicate a design with only HTML and CSS
- Stack Overflow - random value from array
- CSS Tricks - array of country names
- Stack Overflow - can't access property in object
- Stack Overflow - multiple queries in react-query
- Stack Overflow - Strict Mode now shows double console.logs
- Stack Overflow - create array with random values
- Stack Overflow - add unique values to array
- Github - useQueries and config object
- Stack Overflow - usequery with useeffect
- MDN Docs - tabindex
- YouTube - test react query components
- Blog - testing react query