Created
March 29, 2016 01:55
-
-
Save radekstepan/bdd414e2bce6668013f5 to your computer and use it in GitHub Desktop.
rangle-react
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
// Don't forget the imports. | |
import React from 'react'; | |
import ReactDOM from 'react-dom'; | |
const JSON_URL = "https://api.example.io/comments.json"; | |
class Store { | |
constructor(data) { | |
this.data = data; | |
this.cbs = []; | |
} | |
// Register a callback function when change happens on the store. | |
onAny(cb) { | |
this.cbs.push(cb); | |
} | |
// Emit a change event to listeners. | |
emit() { | |
// Maybe pass the data associated with this change as fn params. | |
this.cbs.forEach((cb) => cb()); | |
} | |
// A Comments Store specific function which fetches comments on the client. | |
_getComments() { | |
if (process.browser) { | |
$.ajax({ | |
'url': JSON_URL, | |
'dataType': 'json', | |
'success': ((data) => { | |
// This would emit a change event. | |
this.data.comments = data; | |
this.emit(); | |
}), | |
// This could call a system error handler and show a message in the ui. | |
'error': ((xhr, text) => this.data.error = text) | |
}); | |
} | |
} | |
} | |
class CommentList extends React.Component { | |
render() { | |
let { store } = this.props; | |
let comments; | |
if (store.comments) { | |
comments = store.comments.map(({ key, body, author }, i) => { | |
return ( | |
<li key={key}> | |
{body}—{author} | |
</li> | |
); | |
}); | |
} | |
return <ul>{comments}</ul>; | |
} | |
} | |
class App extends React.Component { | |
constructor() { | |
super(); | |
this.state = { 'store': store.data }; | |
} | |
componentDidMount() { | |
store.onAny(() => { | |
this.setState({ 'store': store.data }); | |
}); | |
} | |
componentWillUnmount() { | |
// TODO: stop listening to any events. | |
} | |
// Here could be a router for the app. Once it decides on the page to show, it | |
// would also trigger a request for data here by emitting a named event. | |
render() { | |
return <CommentList store={this.state.store} />; | |
} | |
} | |
// Maybe bootstrap store with some initial data here for when we render on server? | |
let store = new Store({}); | |
// Render the root app. | |
ReactDOM.render(<App />, document.getElementById('root')); | |
// NOTE: I personaly use `process.nextTick` to make sure updates don't happen | |
// while components are still rendering/updating when firing store changing evts. | |
store._getComments(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment