Discover how to make your app feel instantly responsive without extra code!
Why useNavigation for pending states in Remix? - Purpose & Use Cases
Imagine clicking a link on a website and having to guess if the page is loading or not because there is no visual sign. You might click multiple times or get frustrated waiting without knowing what's happening.
Manually tracking loading states means writing extra code to handle every possible user action and update the UI. This is easy to forget, causes bugs, and makes the app feel slow or broken.
The useNavigation hook in Remix automatically tells you when navigation is happening. It lets you show loading indicators or disable buttons without extra hassle, making your app feel smooth and responsive.
const [loading, setLoading] = useState(false);
// manually set loading true/false on clicks and fetchesconst navigation = useNavigation();
const loading = navigation.state === 'loading';You can easily show real-time feedback during page changes, improving user trust and experience.
When a user submits a form, useNavigation lets you show a spinner on the submit button until the new page loads, so they know their action is working.
Manual loading state tracking is error-prone and tedious.
useNavigation provides automatic navigation state updates.
This leads to better user feedback and smoother app interactions.
Practice
useNavigation in Remix Framework primarily help you detect?Solution
Step 1: Understand the purpose of useNavigation
useNavigationis a hook that tells you about the current navigation state, such as loading or submitting.Step 2: Identify what it detects
It specifically detects when navigation or form submission is happening, so you can show loading states.Final Answer:
When a navigation or form submission is in progress -> Option AQuick Check:
useNavigation detects navigation state = B [OK]
- Confusing useNavigation with page load completion
- Thinking it detects button clicks directly
- Assuming it tracks server responses
useNavigation in a Remix component?Solution
Step 1: Recall the correct property name
TheuseNavigationhook returns an object with astateproperty that holds the current navigation state.Step 2: Check syntax correctness
const navigation = useNavigation(); const state = navigation.state; correctly callsuseNavigation()and accessesnavigation.state. Other options use wrong property names or omit parentheses.Final Answer:
const navigation = useNavigation(); const state = navigation.state; -> Option AQuick Check:
Correct property is navigation.state = A [OK]
- Using navigation.status instead of navigation.state
- Forgetting parentheses after useNavigation
- Calling navigation.state as a function
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>
);
}Solution
Step 1: Check the condition for disabling the button
The button is disabled whennavigation.state === 'submitting'.Step 2: Check the button text during submission
When submitting, the button text changes to 'Submitting...'. So the button is disabled and shows 'Submitting...'.Final Answer:
<button disabled>Submitting...</button> -> Option DQuick Check:
Disabled + 'Submitting...' text = A [OK]
- Ignoring the disabled attribute
- Showing 'Submit' text during submission
- Confusing 'loading' with 'submitting' state
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>;
}Solution
Step 1: Check how useNavigation is used
The code assignsconst navigation = useNavigation;without parentheses, so navigation is a function reference, not the hook result.Step 2: Understand the impact
Accessingnavigation.statewill cause an error because navigation is not the hook's returned object.Final Answer:
Forgot to call useNavigation as a function -> Option BQuick Check:
useNavigation() must be called with () = C [OK]
- Using useNavigation without ()
- Confusing 'loading' and 'submitting' states
- Assuming React import is mandatory for hooks
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>;Solution
Step 1: Understand navigation.state values
Valid states are 'idle', 'loading', and 'submitting'. 'pending' is not valid.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'.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.Final Answer:
Disables and shows loading for any non-idle state -> Option CQuick Check:
Use state !== 'idle' for all pending states = B [OK]
- Using invalid state names like 'pending'
- Checking only 'loading' or only 'submitting'
- Not showing feedback for all navigation states
Ready to prove it?
Pass the test and this pattern moves unknown
