-
-
Save derekclair/2a3adfe0076b36aefea39593c4148255 to your computer and use it in GitHub Desktop.
Context API - Simple Tree Structure Example
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 from 'react'; | |
import Paper from '@material-ui/core/Paper'; | |
import uuidv4 from 'uuid/v4'; | |
import TreeContext from './contexts/TreeContext'; | |
import Node from './components/Node'; | |
import NodeEditor from './components/NodeEditor'; | |
class Editor extends React.Component { | |
state = { nodes: {}, root: {}, selected: null }; | |
componentDidMount = () => { | |
const rootNode = { | |
uuid: uuidv4(), | |
style: { | |
display: 'flex', | |
}, | |
children: [], | |
}; | |
this.setState({ | |
nodes: { | |
[rootNode.uuid]: rootNode, | |
}, | |
root: rootNode.uuid, | |
selected: rootNode.uuid, | |
}); | |
}; | |
insertNode = (uuid, insert) => { | |
const { nodes } = this.state; | |
const node = { ...nodes[uuid] }; | |
node.children.push(insert.uuid); | |
this.setState({ | |
nodes: { | |
...nodes, | |
[node.uuid]: node, | |
[insert.uuid]: insert, | |
}, | |
}); | |
}; | |
selectNode = uuid => { | |
const { selected } = this.state; | |
if (selected !== uuid) { | |
this.setState({ selected: uuid }); | |
} | |
}; | |
updateNode = update => { | |
const { nodes } = this.state; | |
this.setState({ | |
nodes: { | |
...nodes, | |
[update.uuid]: update, | |
}, | |
}); | |
}; | |
render() { | |
const { nodes, root, selected } = this.state; | |
return ( | |
<TreeContext.Provider | |
value={{ | |
insertNode: this.insertNode, | |
nodes, | |
root, | |
selected, | |
selectNode: this.selectNode, | |
updateNode: this.updateNode, | |
}} | |
> | |
<div> | |
<div | |
style={{ | |
flex: 1, | |
padding: '0 382px 16px 16px', | |
}} | |
> | |
<Node uuid={root} /> | |
</div> | |
<NodeEditor /> | |
</div> | |
</TreeContext.Provider> | |
); | |
} | |
} | |
export default Editor; |
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 from 'react'; | |
import Paper from '@material-ui/core/Paper'; | |
import withTree from '../hocs/withTree'; | |
class Node extends React.PureComponent { | |
render() { | |
const { uuid, tree } = this.props; | |
const node = tree.nodes[uuid] || {}; | |
const selected = uuid === tree.selected; | |
const style = { | |
...node.style, | |
padding: '16px', | |
border: '1px solid #f0f0f0', | |
}; | |
if (selected) { | |
style.outlineStyle = 'solid'; | |
style.outlineColor = 'pink'; | |
} | |
return ( | |
<Paper | |
square | |
elevation={1} | |
style={style} | |
onClick={e => { | |
e.preventDefault(); | |
e.stopPropagation(); | |
tree.selectNode(uuid); | |
}} | |
> | |
{node.children && | |
node.children.length > 0 && | |
node.children.map(uuid => <EnhancedNode uuid={uuid} />)} | |
</Paper> | |
); | |
} | |
} | |
const EnhancedNode = withTree(Node); | |
export default EnhancedNode; |
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 from 'react'; | |
const TreeContext = React.createContext({ | |
deleteNode: () => {}, | |
insertNode: () => {}, | |
nodes: {}, | |
root: null, | |
selected: null, | |
selectNode: () => {}, | |
updateNode: () => {}, | |
}); | |
export default TreeContext; |
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 from 'react'; | |
import TreeContext from '../contexts/TreeContext'; | |
function withTree(Component) { | |
return function TreeComponent(props) { | |
return ( | |
<TreeContext.Consumer> | |
{tree => <Component {...props} tree={tree} />} | |
</TreeContext.Consumer> | |
); | |
}; | |
} | |
export default withTree; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment