Bird
Raised Fist0
Remixframework~10 mins

useNavigation for pending states in Remix - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - useNavigation for pending states
Component Renders
↓
Call useNavigation()
↓
Check navigation.state
↓
Idle
↓
Show normal UI
↓
User triggers navigation
↩Back to Check navigation.state
The component uses useNavigation to check the current navigation state and shows normal UI or pending UI accordingly.
Execution Sample
Remix
const navigation = useNavigation();
if (navigation.state !== 'idle') {
  return <p>Loading...</p>;
}
return <p>Content loaded</p>;
This code shows a loading message while navigation is in progress, otherwise it shows the loaded content.
Execution Table
Stepnavigation.stateCondition CheckedUI RenderedExplanation
1idlenavigation.state !== 'idle'?Content loadedInitial render, no navigation in progress
2loadingnavigation.state !== 'idle'?Loading...User triggered navigation, state is loading
3submittingnavigation.state !== 'idle'?Loading...Form submitting, treated as loading state
4idlenavigation.state !== 'idle'?Content loadedNavigation finished, back to idle state
💡 Navigation state returns to 'idle', so loading UI is removed and normal content is shown
Variable Tracker
VariableStartAfter Step 2After Step 3After Step 4
navigation.stateidleloadingsubmittingidle
Key Moments - 2 Insights
Why does the UI show 'Loading...' when navigation.state is 'submitting'?
Because 'submitting' is also a pending state indicating navigation is in progress, so the UI shows the pending state just like 'loading' (see execution_table rows 2 and 3).
What happens when navigation.state goes back to 'idle'?
The UI switches back to showing the normal content because no navigation is happening (see execution_table row 4).
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table, what UI is rendered at step 3 when navigation.state is 'submitting'?
AContent loaded
BLoading...
CError message
DBlank screen
💡 Hint
Check the 'UI Rendered' column at step 3 in the execution_table
At which step does the navigation.state return to 'idle'?
AStep 1
BStep 2
CStep 4
DStep 3
💡 Hint
Look at the 'navigation.state' column in the execution_table
If navigation.state was never 'loading', what UI would always show?
AContent loaded
BLoading...
CSubmitting message
DError message
💡 Hint
Refer to the variable_tracker and execution_table step 1 where state is 'idle'
Concept Snapshot
useNavigation() returns the current navigation state.
Check navigation.state for 'idle', 'loading', or 'submitting'.
Show pending UI (like 'Loading...') when state is 'loading' or 'submitting'.
Show normal UI when state is 'idle'.
This helps show feedback during page transitions or form submissions.
Full Transcript
This visual trace shows how useNavigation from Remix Framework helps track navigation states. Initially, navigation.state is 'idle', so the component renders normal content. When the user triggers navigation, the state changes to 'loading' or 'submitting', and the UI updates to show a loading message. Once navigation finishes, the state returns to 'idle' and the normal content is shown again. This pattern helps users see feedback during page loads or form submissions, improving user experience.

Practice

(1/5)
1. What does useNavigation in Remix Framework primarily help you detect?
easy
A. When a navigation or form submission is in progress
B. When the user clicks a button
C. When the page has fully loaded
D. When the server sends a response

Solution

  1. Step 1: Understand the purpose of useNavigation

    useNavigation is a hook that tells you about the current navigation state, such as loading or submitting.
  2. Step 2: Identify what it detects

    It specifically detects when navigation or form submission is happening, so you can show loading states.
  3. Final Answer:

    When a navigation or form submission is in progress -> Option A
  4. Quick Check:

    useNavigation detects navigation state = B [OK]
Hint: useNavigation tracks loading or submitting states only [OK]
Common Mistakes:
  • Confusing useNavigation with page load completion
  • Thinking it detects button clicks directly
  • Assuming it tracks server responses
2. Which of the following is the correct way to get the navigation state using useNavigation in a Remix component?
easy
A. const navigation = useNavigation(); const state = navigation.state;
B. const navigation = useNavigation(); const state = navigation.status;
C. const navigation = useNavigation; const state = navigation.state();
D. const navigation = useNavigation(); const state = navigation.navigationState;

Solution

  1. Step 1: Recall the correct property name

    The useNavigation hook returns an object with a state property that holds the current navigation state.
  2. Step 2: Check syntax correctness

    const navigation = useNavigation(); const state = navigation.state; correctly calls useNavigation() and accesses navigation.state. Other options use wrong property names or omit parentheses.
  3. Final Answer:

    const navigation = useNavigation(); const state = navigation.state; -> Option A
  4. Quick Check:

    Correct property is navigation.state = A [OK]
Hint: Remember: useNavigation() returns object with .state property [OK]
Common Mistakes:
  • Using navigation.status instead of navigation.state
  • Forgetting parentheses after useNavigation
  • Calling navigation.state as a function
3. Given this Remix component snippet, what will be rendered when a form submission is in progress?
import { useNavigation } from '@remix-run/react';

export default function SubmitButton() {
  const navigation = useNavigation();
  return (
    <button disabled={navigation.state === 'submitting'}>
      {navigation.state === 'submitting' ? 'Submitting...' : 'Submit'}
    </button>
  );
}
medium
A. <button>Submitting...</button>
B. <button>Submit</button>
C. <button disabled>Submit</button>
D. <button disabled>Submitting...</button>

Solution

  1. Step 1: Check the condition for disabling the button

    The button is disabled when navigation.state === 'submitting'.
  2. Step 2: Check the button text during submission

    When submitting, the button text changes to 'Submitting...'. So the button is disabled and shows 'Submitting...'.
  3. Final Answer:

    <button disabled>Submitting...</button> -> Option D
  4. Quick Check:

    Disabled + 'Submitting...' text = A [OK]
Hint: Button disables and text changes when state is 'submitting' [OK]
Common Mistakes:
  • Ignoring the disabled attribute
  • Showing 'Submit' text during submission
  • Confusing 'loading' with 'submitting' state
4. Identify the error in this Remix component using useNavigation:
import { useNavigation } from '@remix-run/react';

export default function LoadingIndicator() {
  const navigation = useNavigation;
  if (navigation.state === 'loading') {
    return <div>Loading...</div>;
  }
  return <div>Ready</div>;
}
medium
A. Missing import for React
B. Forgot to call useNavigation as a function
C. Incorrect state value 'loading', should be 'submitting'
D. Return statements must be wrapped in parentheses

Solution

  1. Step 1: Check how useNavigation is used

    The code assigns const navigation = useNavigation; without parentheses, so navigation is a function reference, not the hook result.
  2. Step 2: Understand the impact

    Accessing navigation.state will cause an error because navigation is not the hook's returned object.
  3. Final Answer:

    Forgot to call useNavigation as a function -> Option B
  4. Quick Check:

    useNavigation() must be called with () = C [OK]
Hint: Always call useNavigation() with parentheses [OK]
Common Mistakes:
  • Using useNavigation without ()
  • Confusing 'loading' and 'submitting' states
  • Assuming React import is mandatory for hooks
5. You want to disable a submit button and show a spinner only when a form submission or navigation is pending using useNavigation. Which code snippet correctly implements this behavior? A)
const navigation = useNavigation();
return <button disabled={navigation.state === 'loading'}>Submit</button>;
B)
const navigation = useNavigation();
return <button disabled={navigation.state !== 'idle'}>
  {navigation.state !== 'idle' ? 'Loading...' : 'Submit'}
</button>;
C)
const navigation = useNavigation();
return <button disabled={navigation.state === 'submitting'}>
  {navigation.state === 'submitting' ? 'Submitting...' : 'Submit'}
</button>;
D)
const navigation = useNavigation();
return <button disabled={navigation.state === 'pending'}>Submit</button>;
hard
A. Disables only on 'loading' state, missing 'submitting'
B. Disables and shows submitting only during form submission
C. Disables and shows loading for any non-idle state
D. Uses invalid 'pending' state which does not exist

Solution

  1. Step 1: Understand navigation.state values

    Valid states are 'idle', 'loading', and 'submitting'. 'pending' is not valid.
  2. Step 2: Check which snippet covers all pending states

    Disables and shows loading for any non-idle state disables the button and shows loading text whenever state is not 'idle', covering both 'loading' and 'submitting'.
  3. Step 3: Evaluate other options

    A only disables on 'loading' (misses 'submitting'), B disables and shows loading for any non-idle state, C only on 'submitting', D uses invalid state.
  4. Final Answer:

    Disables and shows loading for any non-idle state -> Option C
  5. Quick Check:

    Use state !== 'idle' for all pending states = B [OK]
Hint: Check for state !== 'idle' to cover all pending states [OK]
Common Mistakes:
  • Using invalid state names like 'pending'
  • Checking only 'loading' or only 'submitting'
  • Not showing feedback for all navigation states
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard