Skip to content

Instantly share code, notes, and snippets.

@mech
Forked from dvonlehman/AddContact.jsx
Created April 22, 2016 07:10
Show Gist options
  • Save mech/ebb1ef536d3648c3cc2182fc8320f347 to your computer and use it in GitHub Desktop.
Save mech/ebb1ef536d3648c3cc2182fc8320f347 to your computer and use it in GitHub Desktop.
React without flux or redux complexity
import React from 'react';
import request from 'superagent';
// This import syntax requires the babel transform-export-extensions plugin
import dispatcher, {actions} from '../lib/dispatcher';
export default class AddContact extends React.Component {
submitHandler(event) {
request.post('/api/contacts')
.send({
firstName: this.refs.firstName.value,
lastName: this.refs.lastName.value
}, (err, resp) => {
// Emit the newContact event passing the contact object
dispatcher.emit(actions.newContact, resp.body);
});
}
render() {
return (
<form onSubmit={this.submitHandler.bind(this)}>
<input ref="firstName"/>
<input ref="lastName"/>
<button type="submit">Save Contact</button>
</form>
);
}
}
import React from 'react';
// This import syntax requires the babel transform-export-extensions plugin
import dispatcher, {actions} from '../lib/dispatcher';
export default class ContactList extends React.Component {
renderContact(contact) {
return <li>{contact.firstName} {contact.lastName}</li>;
}
render() {
if (this.props.contactsLoading) return <div>Loading...</div>;
return <ul>{this.props.contacts.map(this.renderContact.bind(this))}</ul>;
}
}
ContactList.propTypes = {
contacts: React.PropTypes.array,
contactsLoading: React.PropTypes.bool
};
// You can use any number of event emitter modules from npm
import {emitter} from 'contra';
const deleteContact = 'DELETE_CONTACT';
const newContact = 'NEW_CONTACT';
const _emitter = emitter();
export default {
emit: _emitter.emit,
on: _emitter.on
};
// Export actions seperately to support a more terse way to reference
export const actions = {deleteContact, newContact};
import React from 'react';
import ReactDOM from 'react-dom';
import {Route, Router, Redirect} from 'react-router';
import { createHistory } from 'history';
import request from 'superagent';
import Layout from './Layout';
import ContactList from './ContactList';
import NewContact from './NewContact';
import dispatcher, {actions} from '../lib/dispatcher';
const HISTORY = createHistory();
export default class Root extends React.Component {
constructor() {
super();
this.state = {
contactsLoading: true
};
this.listenForEvents();
}
componentWillMount() {
// Asynchronously load the contacts when the app first bootstraps
request.get('/api/contacts').end((err, resp) => {
this.setState({
contactsLoading: false,
contacts: resp.body
});
});
}
listenForEvents() {
dispatcher.on(actions.newContact, contact => {
this.setState({contacts: this.state.contacts.concat(contact)});
});
dispatcher.on(actions.deleteContact, contact => {
// Set contacts to a new array with the deleted contact eliminated
this.setState({contacts: this.state.contacts.filter(c => c !== contact)});
});
}
createElement(Component, props) {
// Pass the combined props arg with the state as props
return React.createElement(Component, Object.assign({}, props, this.state));
}
render() {
return (
<Router history={HISTORY} createElement={this.createElement.bind(this)}>
<Route component={Layout}>
<Route path="/" component={ContactList} />
<Route path="/add" component={AddContact}/>
</Route>
</Router>
);
}
}
ReactDOM.render(<Root />, document.getElementById('app'));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment