Last active
October 16, 2021 11:08
-
-
Save naholyr/f2f49066fb8dca1439fd0c824ac6f157 to your computer and use it in GitHub Desktop.
This file contains 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
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')); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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…