Created
January 13, 2018 15:21
-
-
Save caub/fb8190da382c1cd2cfbfead7ec70439a to your computer and use it in GitHub Desktop.
React context demo
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
// https://codesandbox.io/s/jznpj65nm5 | |
// ------- index.js | |
import React from 'react'; | |
import { render } from 'react-dom'; | |
import Hello from './Hello'; | |
import DataProvider from './DataProvider'; | |
import * as data from './dataStore'; | |
const styles = { | |
fontFamily: 'sans-serif' | |
}; | |
const App = () => ( | |
<DataProvider data={data}> | |
<div style={styles}> | |
<Hello name="Context demo ✨" /> | |
</div> | |
</DataProvider> | |
); | |
render(<App />, document.getElementById('root')); | |
// ------- withData (like a withContext for this case) | |
import React from 'react'; | |
import PropTypes from 'prop-types'; | |
export default selector => Child => class extends React.Component { | |
static contextTypes = { | |
data: PropTypes.object, | |
dispatch: PropTypes.function | |
}; | |
render() { | |
console.log(this.context); | |
return <Child {...this.props} {...selector(this.context)} />; | |
} | |
} | |
// ---- dataStore.js | |
export const sheeps = new Map(); | |
export const goats = new Map(); | |
// ------ actions.js | |
let i = 0; | |
export const addSheep = (state) => ({ | |
...state, | |
sheeps: new Map(state.sheeps.set(i++, 'sheepee')) | |
}); | |
let j = 0; | |
export const addGoat = (state) => ({ | |
...state, | |
goats: new Map(state.goats.set(j++, 'goatee' + Math.random())) | |
}); | |
// ----- DataProvider.js | |
import React from 'react'; | |
import PropTypes from 'prop-types'; | |
export default class DataProvider extends React.Component { | |
static childContextTypes = { | |
data: PropTypes.object, | |
dispatch: PropTypes.function | |
} | |
getChildContext() { | |
return { | |
data: this.props.data, | |
dispatch: data => this.setState(data) | |
}; | |
} | |
render() { | |
console.log('render'); | |
return ( | |
<div> | |
{this.props.children} | |
</div> | |
); | |
} | |
} | |
// ------ World.js | |
import React from 'react'; | |
import withData from './withData'; | |
import {addGoat} from './actions'; | |
const Foo = ({ name, goats = [], addGoat }) => ( | |
<div> | |
<button onClick={addGoat}>Click</button> | |
<ul>{goats.map((goat,i) => <li key={i}>{goat}</li>)}</ul> | |
</div> | |
); | |
const selector = ({ data: { goats = new Map() } = {}, data, dispatch }) => ({ | |
goats: [...goats.values()], | |
addGoat: e => dispatch(addGoat(data)) | |
}) | |
export default withData(selector)(Foo); | |
// ------ Hello.js | |
import React from 'react'; | |
import World from './World'; | |
export default ({ name}) => ( | |
<div> | |
<h1>{name}</h1> | |
<World /> | |
</div> | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment