-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Description
Hi,
I think this component only succeeds by accident because the camel-case string that comes back from the GitHub API ("MoonHighway") differs in case from the lowecase string the book passes as the prop ("moonhighway"). If you, more correctly, pass the the exact casing that GitHub returns as the prop to the GitHubUser
component , then nothing is ever cached?
So the caching strategy silently fails for any user who types the exact case GitHub uses (or for any API that preserves case). The guard:
if (data.login === login) return;
is the culprit: it blocks the very moment we actually want to write - on the second triggering of the [data]
useEffect, by setData
being called post fetch - here we will return before saving if data.login === login
which is true if we set login==="MoonHighway"
, rather than using the subtley different login==="moonhighway"
given in the example which will fail to match "MoonHighway".
I only tested it quickly but I think a valid fix that achieves the desired result is to check for a valid key existing using loadJSON
. The text quotes:
Also, if the current login and data.login are equal to each other, then we already have saved data for that user.
My proposed fix:
useEffect(() => {
if (!data) return;
if (loadJSON(`user:${login}`)) return; // already cached → skip
const { name, avatar_url, location } = data;
saveJSON(`user:${login}`, {
name,
login,
avatar_url,
location
});
}, [data]);
Logins differ on first run - highlighted in code and output in pink:
Then on refresh they match because we store the props login not the data.login:
But if I correct the login hardcoded in the code to match exactly the case provided by GitHub, and pass this as a prop, then no matter how often I refresh it always fetches the full remote json:
Below are text copies of the initial and subsequent result.
Inital result with CamelCase login - MoonHighway:
{
"login": "MoonHighway",
"id": 5952087,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjU5NTIwODc=",
"avatar_url": "https://avatars.githubusercontent.com/u/5952087?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/MoonHighway",
"html_url": "https://github.com/MoonHighway",
"followers_url": "https://api.github.com/users/MoonHighway/followers",
"following_url": "https://api.github.com/users/MoonHighway/following{/other_user}",
"gists_url": "https://api.github.com/users/MoonHighway/gists{/gist_id}",
"starred_url": "https://api.github.com/users/MoonHighway/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/MoonHighway/subscriptions",
"organizations_url": "https://api.github.com/users/MoonHighway/orgs",
"repos_url": "https://api.github.com/users/MoonHighway/repos",
"events_url": "https://api.github.com/users/MoonHighway/events{/privacy}",
"received_events_url": "https://api.github.com/users/MoonHighway/received_events",
"type": "Organization",
"user_view_type": "public",
"site_admin": false,
"name": "Moon Highway",
"company": null,
"blog": "http://www.moonhighway.com",
"location": "United States of America",
"email": "[email protected]",
"hireable": null,
"bio": "Web Development classroom training materials.",
"twitter_username": "moonhighway",
"public_repos": 88,
"public_gists": 0,
"followers": 181,
"following": 0,
"created_at": "2013-11-15T23:34:26Z",
"updated_at": "2025-03-28T17:07:53Z"
}
An example of the stored version with lowercase username moonhighway:
{
"name": "Moon Highway",
"login": "moonhighway",
"avatar_url": "https://avatars.githubusercontent.com/u/5952087?v=4",
"location": "United States of America"
}