Skip to content

Instantly share code, notes, and snippets.

@naholyr
Last active October 16, 2021 11:08
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save naholyr/f2f49066fb8dca1439fd0c824ac6f157 to your computer and use it in GitHub Desktop.
Save naholyr/f2f49066fb8dca1439fd0c824ac6f157 to your computer and use it in GitHub Desktop.
import React, { Fragment, Component } from 'react';
import ReactDOM from 'react-dom';
class ContextData {
watchers = []
constructor(initialState = {}) {
this.state = initialState
}
watch(fn) {
this.watchers = this.watchers.concat([fn])
return () => this.watchers = this.watchers.filter(f => f !== fn)
}
update(state) {
this.state = Object.assign({}, this.state, state)
this.watchers.forEach(fn => fn(this.state))
}
}
const createContextComponent = initialState => {
const store = new ContextData(initialState)
const update = store.update.bind(store)
return class extends Component {
state = initialState
componentWillMount () {
this.unwatch = store.watch(state => this.setState(state))
}
componentWillUnmount () {
this.unwatch()
}
render() {
console.log('Context.render')
return this.props.children({
state: this.state,
update,
})
}
}
}
const Context = createContextComponent({
lang: 'fr'
})
const App = () => console.log('App.render') || (
<Fragment>
<h1>Coucou</h1>
<p>This is some text with inner text: <StupidInnerText /></p>
<Footer />
</Fragment>
)
const StupidInnerText = () => console.log('StupidInnerText.render') || (
<span>
stupid useless text just to say you selected
<Context>
{ ({ state }) => console.log('StupidInnerText.innerRender') || (
<strong> { state.lang } </strong>
) }
</Context>
that's all
</span>
)
const Footer = () => console.log('Footer.render') || (
<Fragment>
<hr />
<LangSelector />
</Fragment>
)
const LangSelector = () => console.log('LangSelector') || (
<Context>
{ ({ state, update }) => console.log('LangSelector.innerRender') || (
<select
value={ state.lang }
onChange={ e => update({ lang: e.target.value }) }
>
<option value="en">en</option>
<option value="fr">fr</option>
<option value="it">it</option>
<option value="es">es</option>
</select>
) }
</Context>
)
ReactDOM.render(<App />, document.getElementById('root'));
@naholyr
Copy link
Author

naholyr commented Mar 19, 2018

Removed mentions of reducers to avoid confusion with the main goal which is playing with context without context to understand why the new API seems so bloated. I still don't get it though…

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