Created
January 3, 2018 16:59
-
-
Save tweinfeld/62f96732a65d7d81043ced7a1f01a9c2 to your computer and use it in GitHub Desktop.
An example of utilizing HTML5's History API in order to save and restore state. Whenever the state changes, a copy of it is stored in History whether it effected the URL route or not. It comes to demonstrate the somewhat concealed benefits of the History API.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<script src="https://unpkg.com/[email protected]/dist/kefir.min.js"></script> | |
<script src="https://unpkg.com/[email protected]/lodash.min.js"></script> | |
<script src="https://unpkg.com/[email protected]/umd/react.development.js"></script> | |
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script> | |
</head> | |
<body> | |
<main/> | |
<script> | |
const | |
urlTemplate = ({ currentPage, currentItem })=> "/"+ _.compact([currentPage, currentPage === "item" && currentItem]).join('/'), | |
generateRandomState = (function(counter){ | |
return ()=> ({ | |
id: ++counter, | |
currentPage: _.sample(["welcome", "item"]), | |
currentItem: _.random(5, 1), | |
someRandomNumber: _.random(100), | |
someRandomAnimal: _.sample(["cat", "dog", "mouse"]) | |
}); | |
})(0); | |
let | |
statePushStream = Kefir.pool(), | |
applicationState = statePushStream.toProperty(), | |
activeUrlStream = applicationState.map(urlTemplate); | |
// Update address bar view (push) | |
applicationState | |
.sampledBy(activeUrlStream, (state, url)=> ({ ...state, _url: url })) | |
.onValue(({ _url, ...state })=> window.history[window.location.pathname !== _url ? "pushState" : "replaceState"](state, '', _url)); | |
// Restore state back from address bar | |
Kefir | |
.fromEvents(window, 'popstate') | |
.map(()=> window.history.state) | |
.toProperty(()=> window.history.state || {}) | |
.onValue((state)=> statePushStream.plug(Kefir.constant(state))); | |
// Update dom view | |
applicationState | |
.onValue((function(mainEl){ | |
const [div, ul, li, button] = ["div", "ul", "li", "button"].map((tagName)=> _.partial(React.createElement, tagName)); | |
return function({ someRandomAnimal, currentItem, currentPage, someRandomNumber }){ | |
return ReactDOM.render(div({}, [], ...[ | |
ul({}, [], ...[ | |
li({}, `Page: ${currentPage}`), | |
li({}, `Item: ${currentItem}`), | |
li({}, `Animal: ${someRandomAnimal}`), | |
li({}, `Number: ${someRandomNumber}`) | |
]), | |
button({ onClick: ()=> statePushStream.plug(Kefir.constant(generateRandomState())) }, 'Generate Random State') | |
]), mainEl); | |
}; | |
})(document.querySelector('main'))); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment