react-navigation/website/src/BrowserAppContainer.js

141 lines
3.9 KiB
JavaScript
Raw Normal View History

import React from 'react';
import PropTypes from 'prop-types';
import { NavigationActions, addNavigationHelpers } from 'react-navigation';
function getAction(router, path, params) {
const action = router.getActionForPathAndParams(path, params);
if (action) {
return action;
}
return NavigationActions.navigate({
params: { path },
routeName: 'NotFound',
});
}
export default NavigationAwareView => {
const initialAction = getAction(
NavigationAwareView.router,
window.location.pathname.substr(1)
);
const initialState = NavigationAwareView.router.getStateForAction(
initialAction
);
console.log({ initialAction, initialState });
class NavigationContainer extends React.Component {
state = initialState;
componentDidMount() {
const navigation = addNavigationHelpers({
state: this.state.routes[this.state.index],
dispatch: this.dispatch,
});
document.title = NavigationAwareView.router.getScreenOptions(
navigation
).title;
window.onpopstate = e => {
e.preventDefault();
const action = getAction(
NavigationAwareView.router,
window.location.pathname.substr(1)
);
if (action) this.dispatch(action);
};
}
componentWillUpdate(props, state) {
const {
path,
params,
} = NavigationAwareView.router.getPathAndParamsForState(state);
2017-04-18 15:25:12 +02:00
const maybeHash = params && params.hash ? `#${params.hash}` : '';
const uri = `/${path}${maybeHash}`;
if (window.location.pathname !== uri) {
window.history.pushState({}, state.title, uri);
}
const navigation = addNavigationHelpers({
state: state.routes[state.index],
dispatch: this.dispatch,
});
document.title = NavigationAwareView.router.getScreenOptions(
navigation
).title;
}
2017-04-18 15:25:12 +02:00
componentDidUpdate() {
const { params } = NavigationAwareView.router.getPathAndParamsForState(
this.state
);
2017-04-18 15:25:12 +02:00
if (params && params.hash) {
document.getElementById(params.hash).scrollIntoView();
}
}
dispatch = action => {
const state = NavigationAwareView.router.getStateForAction(
action,
this.state
);
if (!state) {
console.log('Dispatched action did not change state: ', { action });
} else if (console.group) {
console.group('Navigation Dispatch: ');
console.log('Action: ', action);
console.log('New State: ', state);
console.log('Last State: ', this.state);
console.groupEnd();
} else {
console.log('Navigation Dispatch: ', {
action,
newState: state,
lastState: this.state,
});
}
if (!state) {
return true;
}
if (state !== this.state) {
this.setState(state);
return true;
}
return false;
};
render() {
return (
<NavigationAwareView
navigation={addNavigationHelpers({
state: this.state,
dispatch: this.dispatch,
})}
/>
);
}
getURIForAction = action => {
const state =
NavigationAwareView.router.getStateForAction(action, this.state) ||
this.state;
const { path } = NavigationAwareView.router.getPathAndParamsForState(
state
);
return `/${path}`;
};
getActionForPathAndParams = (path, params) => {
return NavigationAwareView.router.getActionForPathAndParams(path, params);
};
static childContextTypes = {
getActionForPathAndParams: PropTypes.func.isRequired,
getURIForAction: PropTypes.func.isRequired,
dispatch: PropTypes.func.isRequired,
};
getChildContext() {
return {
getActionForPathAndParams: this.getActionForPathAndParams,
getURIForAction: this.getURIForAction,
dispatch: this.dispatch,
};
}
}
return NavigationContainer;
};