- 
                Notifications
    You must be signed in to change notification settings 
- Fork 699
URL-based navigation for slides. #711
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
| deckContextState.currentSlideElement === slideElementsLength | ||
| ) { | ||
| deckContextDispatch({ type: 'NEXT_SLIDE' }); | ||
| navigateToNextSlide(); | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We want all slide navigation to go through the router otherwise the URL will become out of sync.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a way to prevent/scare off people from dispatching directly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Internally not really. But we're not exposing the dispatcher to the user.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Using a hook for routing is a little strange but I trust your judgement :D
| React.useEffect(() => { | ||
| /*** | ||
| * This will look at the current query string and navigate to whatever | ||
| * slide is specified, otherwise start at 0. This only runs once per mount | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This effect will run again if navigateToCurrentUrl changes. If you want to guarantee it runs only on mount, you'll need to use an empty array for dependencies
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but the ESLint rule does require any used functions or variables to be inside the dependency array. So we have no choice but to include it. Since that function will not change, it has the same effect.
| function reducer(state, action) { | ||
| switch (action.type) { | ||
| case 'NEXT_SLIDE': | ||
| return { | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like how simple this code became!
| numberOfSlides - 1 < proposedSlideNumber | ||
| ) { | ||
| const qs = queryString.stringify({ slide: 0 }); | ||
| history.current.replace(`?${qs}`); | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This updates the url directly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It replaces the invalid url in the history stack with a valid one. That way they can't "go back" to the invalid URL and then get stuck in re-direction limbo.
        
          
                src/hooks/use-url-routing.js
              
                Outdated
          
        
      | }); | ||
| history.current.push(`?${qs}`); | ||
| }, | ||
| [currentSlide, presenterMode] | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should loop be included in the dep array?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes.
Let the URL do the talking!
This keeps the URL in sync with the current slide. It also lets the user navigate to the correct slide on load as well. We use query params because it's specific (we will have additional ones for presenter mode) and it doesn't force a certain server to direct the routes. Meaning it works with webpack dev server out of the box.
The other benefit is each slide navigation change becomes a back/forward history stack within the browser.
If the user enters a slide index that doesn't exist or an invalid index we replace the current history stack item with 0 and pretend the invalid index never occurred.