Latest Ref

Loading "Latest Ref"
πŸ‘¨β€πŸ’Ό In our exercise, we have a useDebounce function that isn't working the way we want with hooks. We're going to need to "change the default" using the latest ref pattern.
debounce is a pattern that's often used in user-input fields. For example, if you've got a signup form where the user can select their username, you probably want to validate for the user that the username is not taken. You want to do it when the user's done typing but without requiring them to do anything to trigger the validation. With a debounced function, you could say when the user stops typing for 400ms you can trigger the validation. If they start typing again after only 350ms then you want to start over and wait again until the user pauses for 400ms.
In this exercise, the debounce function is already written. Even the useDebounce hook is implemented for you. Your job is to implement the latest ref pattern to fix its behavior.
Our example here is a counter button that has a debounced increment function. We want to make it so this works:
  • The step is 1
  • The user clicks the button
  • The user updates the step value to 2
  • The user clicks the button again (before the debounce timer completes)
  • The debounce timer completes for both clicks
  • The count value should be 2 (instead of 1)
(Keep in mind, the tests are there to help you know you got it right).
Before continuing here, please familiarize yourself with the code to know how it's implemented... Got it? Great, let's continue.
Right now, you can play around with two different problems with the way our exercise is implemented:
// option 1:
// ...
const increment = () => setCount(c => c + step)
const debouncedIncrement = useDebounce(increment, 3000)
// ...
The problem here is useDebounce list increment in the dependency list for useMemo. For this reason, any time there's a state update, we create a new debounced version of that function so the timer in that debounce function's closure is different from the previous which means we don't cancel that timeout. Ultimately this is the bug our users experience:
  • The user clicks the button
  • The user updates the step value
  • The user clicks the button again
  • The first debounce timer completes
  • The count value is incremented by the step value at the time the first click happened
  • The second debounce timer completes
  • The count value is incremented by the step value at the time the second click happened
This is not what we want at all! And the reason it's a problem is because we're not memoizing the callback that's going into our useMemo dependency list.
So the alternative solution is we could change our useDebounce API to require you pass a memoized callback:
// option 2:
// ...
const increment = useCallback(() => setCount(c => c + step), [step])
const debouncedIncrement = useDebounce(increment, 3000)
// ...
But again, this callback function will be updated when the step value changes which means we'll get another instance of the debouncedIncrement. Dah! So the user experience doesn't actually change with this adjustment and we have a less fun API. The latest ref pattern will give us a nice API and we'll avoid this problem.
I've made the debounce value last 3000ms to make it easier for you to observe and test the behavior, but you can feel free to adjust that as you like. The tests can also help you make sure you've got things working well.
The debounce behavior means that this will make the tests a bit slow. Don't worry though, the rest of the tests will be quite fast.
Login to get access to the exclusive discord channel.
  • General
    Interviews with Experts -> Start Watching CTA gives regional restricted license error
    .shreyasvaidya πŸš€:
    I have purchased my course from India with the regional pricing method, and I am trying to watch the...
    • βœ…1
    4 Β· 8 days ago
  • General
    You are offline - warning
    marianavinyolas 🌌 πŸš€:
    Hi there! Today I want to start with the Advanced Patterns workshop, but after clone and run the rep...
    • βœ…1
    3 Β· 11 days ago
  • General
    βš›οΈFundamentals
    Clicking on index.html when start opens in Terminal and not on the editor.
    Waddle πŸš€:
    Hello, just starting out with this and noticed that when I click on the 'index.html' file as display...
    • βœ…2
    1 Β· 18 days ago
  • General
    Welcome to EpicReact.dev! Say Hello πŸ‘‹
    Kent C. Dodds β—† πŸš€πŸ†πŸŒŒ:
    Welcome to the first of many posts in the EpicReact.dev channel! Take a moment to introduce yourself...
    • πŸš€6
    58 Β· 10 days ago
  • General
    Am I following the course in the proper way?
    bauti πŸš€ 🌌:
    The way im doing things in epic-react is: Clone the repo for the module i want to do (for example a...
    • βœ…1
    3 Β· a month ago
  • 🎣Hooks
    General
    VSCode imports from wrong source
    mathemaat πŸš€:
    I encountered something silly that threw me off for a minute or two. I was working on the Tic Tac To...
    • βœ…1
    1 Β· 2 months ago
  • General
    Terminal Errors When Running Workshop App
    Giovanni πŸš€:
    Hello guys, I am facing an issue with the Workshop App, that basically I get this message over and...
    • βœ…1
    3 Β· 2 months ago
  • General
    Launch editor error: spawn code ENOENT
    Andrew Elans 🌌 πŸš€:
    Clicking index.html gives this error in VS Code. Both from Chrome and Safari. Anyone?
    • βœ…2
    6 Β· 6 months ago
  • General
    Cannot connect workshop app
    Philipp πŸš€:
    I try to connect with my Company MacBook and get the following error 😦 There was an error: unable t...
    • βœ…1
    5 Β· 3 months ago
  • General
    Problem generating the diff
    mikeyjmcc πŸš€:
    I am not sure what has changed but I am now receiving errors that the diff cannot be generated. This...
    • βœ…2
    1 Β· 3 months ago
  • General
    Problem with playground
    Xrayoptions πŸš€:
    Problem section doesn't show <@105755735731781632> how to fix it ?
    • βœ…1
    9 Β· 3 months ago
  • General
    How to run tests in IDE?
    anonymousBlack10:
    Is it possible to run the tests from the IDE or are they setup to be run just from the browser? Some...
    • βœ…1
    1 Β· 4 months ago
  • 🀯Advanced Patterns
    When to Use Slots Pattern vs. Compound Components
    sykhanh196:
    I'm currently learning advanced React patterns and have some questions. The slots pattern seems to e...
    • βœ…1
    1 Β· 4 months ago
  • General
    Launch editor error: Could not open 'index.html' from:'playground' in the editor.
    Japhet πŸš€ πŸ† 🌌:
    I'm encountering an issue when trying to open a link from the file list. The error message I receive...
    • βœ…1
    15 Β· 6 months ago
  • General
    AI Assistant?
    John πŸš€:
    Kent has mentioned an AI assistant that he's using in VSCode. Is there any detail on what that is an...
    • βœ…2
    2 Β· 5 months ago
  • General
    Script to save playground folder
    larissapissurno πŸš€:
    Hi all, I personally like to take notes on the playground files, so in order to not lose this notes ...
    • βœ…1
    2 Β· 6 months ago
  • General
    Runninng Learning app on iPad?
    marcus_polonus πŸš€ 🌌:
    Hi all, Did anyone managed to setup learning app on iPad? I tried to use codesandbox, but when I am...
    • βœ…1
    1 Β· 6 months ago
  • General
    βš›οΈFundamentals
    Error boundary good practice
    Lloren πŸš€:
    I have always wondered if the error boundary is there a limit of error boundary that you can impleme...
    • βœ…1
    1 Β· 6 months ago
  • General
    Received this error when running the setup script for React Fundamentals
    ChrisP πŸš€:
    Hey guys, I am completely blocked at the moment. When I clone and run the setup for react fundamenta...
    • βœ…1
    2 Β· 6 months ago
  • General
    Unexpected server error (workshop-app does not load onboarding step)
    Matias 🌌 πŸš€:
    Hey! πŸ‘‹ I installed the free workshop "Build React Hooks" last week with no issues. Yesterday, whe...
    • βœ…1
    3 Β· 6 months ago
  • General
    Eye opening moment in 05/06 (β€žsatisfiesβ€œ operator of typescript)
    Chrigi πŸš€:
    Up until today I was not aware that having the type annotation on a variable is actually a type-cast...
    • πŸ™Œ2
    • βœ…1
    2 Β· 6 months ago
  • General
    Failed to fetch dynamically imported module...
    FacuPerezM 🌌:
    I am getting this error out of nowhere, in the 'test' tab inside the Workshop app. ``` Failed to f...
    • βœ…1
    3 Β· 6 months ago
  • General
    Epicshop not saving the video resolution
    Toni πŸš€ 🌌:
    Playback speed and caption settings are saved, but the video resolution always defaults to auto. Is ...
    • βœ…1
    7 Β· 6 months ago
  • General
    Clicking an exercise file launch VIM instead of VS Code
    DBattou πŸš€:
    I started going through the workshops, everything is setup and working fine except for opening a fil...
    • βœ…1
    2 Β· 6 months ago