Skip to content

Instantly share code, notes, and snippets.

@RobinMalfait
Last active September 13, 2016 21:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RobinMalfait/a91a43dca2d4f2314899b0c6f0cecf52 to your computer and use it in GitHub Desktop.
Save RobinMalfait/a91a43dca2d4f2314899b0c6f0cecf52 to your computer and use it in GitHub Desktop.
I wonder if there is a way to override/enhance setState. I keep getting this error: http://d.pr/i/LVAF+ and http://d.pr/i/X2Vo+ so I wonder if this is do-able?
/**
* I want to write a HOC, that can intercept the setState functionality
*
* For some context: I'm writing a personal assistant: https://github.com/SmithersAssistant/Smithers
* and I have a plugin system, now I want to store the state of plugins into localStorage
* so that later on I can restore the state
*
* Ideally I would want something like this:
*/
const NOOP = () => {}
const restorableComponent = (Component) => {
return React.createClass({
componentDidMount () {
if (this.component) {
const originalSetState = this.component.setState || NOOP
const originalGetInitialState = this.component.getInitialState || NOOP;
this.component.setState = (newState = {}, cb = NOOP) => {
console.log('storing state of component') // Pretending to store it...
return originalSetState(newState, cb)
}
this.component.getInitialState = () => {
const restoredState = {} // Think that this came from the localStorage
return {
...restoredState,
...originalGetInitialState()
}
}
}
},
render () {
return (
<Component
ref={component => this.component = component}
{...this.props}
/>
)
}
})
}
/**
* So I could use it like this:
*
* P.S.: YEAH React.createClass FTW!
*/
const SomePlugin = React.createClass({
getInitialState () {
return {
count: 0
}
},
componentDidMount () {
this._interval = setInterval(() => this.setState({count: this.state.count}))
},
componentWillUnmount () {
clearInterval(this._interval)
},
render () {
return (
<span>Counting {this.state.count}</span>
)
}
})
export default restorableComponent(SomePlugin)
@RobinMalfait
Copy link
Author

Eventually I came up with this:

export default (Component) => {
  class EnhancedClass extends Component {
    constructor (...args) {
      super(...args)

      this.state = {
        ...this.state,
        ...this.props.getState()
      }
    }

    setState (state = {}, cb = () => {}) {
      super.setState(state, cb)
      this.props.setState(state)
    }
  }

  return EnhancedClass
}

@RobinMalfait
Copy link
Author

the this.props.getState() and this.props.setState() are injected via something different. But those allow you to (write to)/(read from) some storage engine like localStorage

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment