Last active
April 17, 2018 15:25
-
-
Save willhoney7/d36cee94feba249b3c1526b91be9032d to your computer and use it in GitHub Desktop.
A React localStorage render props component
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
| // MIT License | |
| // By Will Honey at Operational Results, Inc. | |
| import React from 'react'; | |
| import PropTypes from 'prop-types'; | |
| const SUPPORTS_LOCAL_STORAGE = (function() { | |
| try { | |
| localStorage.setItem('a', 1); | |
| localStorage.removeItem('a'); | |
| return true; | |
| } catch (e) { | |
| return false; | |
| } | |
| })(); | |
| export default class LocalStorage extends React.Component { | |
| static propTypes = { | |
| storageKey: PropTypes.string.isRequired, | |
| render: PropTypes.func.isRequired, | |
| defaultValue: PropTypes.any | |
| }; | |
| getStorageValue = storageKey => { | |
| if (SUPPORTS_LOCAL_STORAGE) { | |
| try { | |
| const value = localStorage.getItem(storageKey); | |
| return value !== undefined && value !== null ? JSON.parse(value).value : undefined; | |
| } catch (er) { | |
| console.warn('Failed to use localStorage. Falling back to component state', er); | |
| } | |
| } | |
| }; | |
| setStorageValue = (storageKey, value) => { | |
| if (SUPPORTS_LOCAL_STORAGE) { | |
| try { | |
| localStorage.setItem(storageKey, JSON.stringify({ value })); | |
| } catch (er) { | |
| console.warn('Failed to use localStorage. Falling back to component state', er); | |
| } | |
| } | |
| }; | |
| constructor(props) { | |
| super(props); | |
| const storageValue = this.getStorageValue(this.props.storageKey); | |
| this.state = { value: storageValue !== undefined ? storageValue : this.props.defaultValue }; | |
| } | |
| setValue = value => { | |
| this.setState({ value }); | |
| this.setStorageValue(this.props.storageKey, value); | |
| }; | |
| render() { | |
| return this.props.render(this.state.value, this.setValue); | |
| } | |
| } | |
| export const withLocalStorage = localStorageProps => Component => props => ( | |
| <LocalStorage | |
| {...localStorageProps} | |
| render={(value, setValue) => <Component value={value} setValue={setValue} {...props} />} | |
| /> | |
| ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Usage
or
Notes
This won't work well if you need to access the same localStorage value in different locations. They will get out of sync. If you need that, use React 16.3's new context API.