Correctly update page when url changed

This commit is contained in:
Samy Pesse
2016-10-04 18:32:31 +02:00
parent 87ae2481e4
commit 16ca48b2c0
7 changed files with 68 additions and 54 deletions
@@ -7,6 +7,7 @@ module.exports = {
NAVIGATION_ACTIVATE: 'navigation/activate',
NAVIGATION_DEACTIVATE: 'navigation/deactivate',
NAVIGATION_LISTEN: 'navigation/listen',
NAVIGATION_UPDATE: 'navigation/update',
PAGE_FETCH_START: 'navigation/fetch:start',
PAGE_FETCH_END: 'navigation/fetch:end',
PAGE_FETCH_ERROR: 'navigation/fetch:error',
+24 -17
View File
@@ -14,9 +14,27 @@ const SUPPORTED = (
*/
function activate() {
return (dispatch, getState) => {
dispatch({
type: ACTION_TYPES.NAVIGATION_ACTIVATE,
listener: () => dispatch(emit())
listener: (location) => {
location = Location.fromNative(location);
const prevLocation = getState().navigation.location;
// Fetch page if required
if (!prevLocation || location.pathname !== prevLocation.pathname) {
dispatch(fetchPage(location.pathname));
}
// Signal location to listener
dispatch(emit());
// Update the location
dispatch({
type: ACTION_TYPES.NAVIGATION_UPDATE,
location
});
}
});
// Trigger for existing listeners
@@ -116,24 +134,14 @@ function listen(listener) {
/**
* Fetch a new page and update the store accordingly
* @param {String} uri
* @param {Boolean} options.replace
* @param {String} pathname
* @return {Action} action
*/
function fetchPage(uri, options = {}) {
const shouldReplace = options.replace;
function fetchPage(pathname) {
return (dispatch, getState) => {
const prevURI = location.href;
dispatch({ type: ACTION_TYPES.PAGE_FETCH_START });
if (shouldReplace) {
dispatch(replace(uri));
} else {
dispatch(push(uri));
}
window.fetch(uri, {
window.fetch(pathname, {
credentials: 'include'
})
.then(
@@ -154,9 +162,8 @@ function fetchPage(uri, options = {}) {
)
.catch(
error => {
dispatch(replace(prevURI));
dispatch(redirect(uri));
// dispatch(redirect(pathname));
console.error(error);
dispatch({ type: ACTION_TYPES.PAGE_FETCH_ERROR, error });
}
);
@@ -1,6 +1,6 @@
const React = require('react');
const ReactRedux = require('react-redux');
const navigation = require('../actions/navigation');
const Navigation = require('../actions/navigation');
/**
* Check if an element is inside a link
@@ -61,7 +61,7 @@ function getHrefForEvent(event) {
if (link.getAttribute('data-nopjax'))
return;
return link.href;
return link.pathname;
}
/*
@@ -83,25 +83,15 @@ const PJAXWrapper = React.createClass({
}
event.preventDefault();
dispatch(navigation.fetchPage(href));
},
onPopState(event) {
const { dispatch } = this.props;
event.preventDefault();
dispatch(navigation.fetchPage(location.href, { replace: true }));
dispatch(Navigation.push(href));
},
componentDidMount() {
document.addEventListener('click', this.onClick, false);
window.addEventListener('popstate', this.onPopState, false);
},
componentWillUnmount() {
document.removeEventListener('click', this.onClick, false);
window.removeEventListener('popstate', this.onPopState, false);
},
render() {
@@ -10,6 +10,11 @@ const DEFAULTS = {
};
class Location extends Record(DEFAULTS) {
/**
* Return search query as a string
* @return {String}
*/
get search() {
const { query } = this;
return query.size === 0 ?
+22
View File
@@ -0,0 +1,22 @@
const { Record } = require('immutable');
const DEFAULTS = {
title: '',
content: '',
dir: 'ltr',
depth: 1,
level: '',
previous: null,
next: null
};
class Page extends Record(DEFAULTS) {
static create(state) {
return state instanceof Page ?
state : new Page({
...state
});
}
}
module.exports = Page;
@@ -5,16 +5,18 @@ const ACTION_TYPES = require('../actions/TYPES');
const isServerSide = (typeof window === 'undefined');
const NavigationState = Record({
// Current location
location: null,
// Are we loading a new page
loading: Boolean(false),
loading: Boolean(false),
// Did we fail loading a page?
error: null,
error: null,
// Listener for history changes
listeners: List(),
// Function to call to stop listening
unlisten: null,
unlisten: null,
// History instance
history: null
history: null
});
function reduceNavigation(state, action) {
@@ -58,6 +60,11 @@ function reduceNavigation(state, action) {
unlisten: null
});
case ACTION_TYPES.NAVIGATION_UPDATE:
return state.merge({
location: action.location
});
case ACTION_TYPES.NAVIGATION_LISTEN:
return state.merge({
listeners: state.listeners.push(action.listener)
+2 -20
View File
@@ -1,26 +1,8 @@
const { Record } = require('immutable');
const ACTION_TYPES = require('../actions/TYPES');
const DEFAULTS = {
title: '',
content: '',
dir: 'ltr',
depth: 1,
level: '',
previous: null
};
class PageState extends Record(DEFAULTS) {
static create(state) {
return state instanceof PageState ?
state : new PageState({
...state
});
}
}
const Page = require('../models/Page');
module.exports = (state, action) => {
state = PageState.create(state);
state = Page.create(state);
switch (action.type) {