From f5d4050e67e79590b2512e6aabcdda1b71d54eff Mon Sep 17 00:00:00 2001
From: Roger Studner
Date: Fri, 30 Oct 2015 21:04:51 -0400
Subject: [PATCH 1/6] ES6 all React stuff.
---
client/app/components/Comment.jsx | 13 +++--
client/app/components/CommentBox.jsx | 19 ++++---
client/app/components/CommentForm.jsx | 50 +++++++++----------
client/app/components/CommentList.jsx | 14 +++---
client/app/components/CommentScreen.jsx | 12 ++---
client/app/components/SimpleCommentScreen.jsx | 32 ++++++------
client/app/reducers/commentsReducer.js | 2 +-
client/app/startup/ClientApp.jsx | 9 ++--
client/app/startup/ServerApp.jsx | 9 ++--
client/app/stores/commentsStore.js | 4 +-
10 files changed, 76 insertions(+), 88 deletions(-)
diff --git a/client/app/components/Comment.jsx b/client/app/components/Comment.jsx
index e3b40d1f..a358bd80 100644
--- a/client/app/components/Comment.jsx
+++ b/client/app/components/Comment.jsx
@@ -1,13 +1,12 @@
import React, { PropTypes } from 'react';
import marked from 'marked';
-const Comment = React.createClass({
- displayName: 'Comment',
-
- propTypes: {
+class Comment extends React.Component {
+ static displayName = 'Comment';
+ static propTypes = {
author: PropTypes.string.isRequired,
text: PropTypes.string.isRequired,
- },
+ };
render() {
const { author, text } = this.props;
@@ -20,7 +19,7 @@ const Comment = React.createClass({
);
- },
-});
+ }
+}
export default Comment;
diff --git a/client/app/components/CommentBox.jsx b/client/app/components/CommentBox.jsx
index 21e805a2..9596048f 100644
--- a/client/app/components/CommentBox.jsx
+++ b/client/app/components/CommentBox.jsx
@@ -3,28 +3,27 @@ import React, { PropTypes } from 'react';
import CommentForm from './CommentForm';
import CommentList from './CommentList';
-const CommentBox = React.createClass({
- displayName: 'CommentBox',
-
- propTypes: {
+class CommentBox extends React.Component {
+ static displayName = 'CommentBox';
+ static propTypes = {
pollInterval: PropTypes.number.isRequired,
actions: PropTypes.object.isRequired,
data: PropTypes.object.isRequired,
- },
+ };
componentDidMount() {
const { fetchComments } = this.props.actions;
fetchComments();
setInterval(fetchComments, this.props.pollInterval);
- },
+ }
ajaxCounter() {
return this.props.data.get('ajaxCounter');
- },
+ }
isSendingAjax() {
return this.ajaxCounter() > 0;
- },
+ }
render() {
const { actions, data } = this.props;
@@ -49,7 +48,7 @@ const CommentBox = React.createClass({
/>
);
- },
-});
+ }
+}
export default CommentBox;
diff --git a/client/app/components/CommentForm.jsx b/client/app/components/CommentForm.jsx
index cbe5c755..f0c5ae15 100644
--- a/client/app/components/CommentForm.jsx
+++ b/client/app/components/CommentForm.jsx
@@ -10,31 +10,27 @@ import ReactCSSTransitionGroup from 'react/lib/ReactCSSTransitionGroup';
const emptyComment = { author: '', text: '' };
const textPlaceholder = 'Say something using markdown...';
-const CommentForm = React.createClass({
- displayName: 'CommentForm',
+class CommentForm extends React.Component {
+ state = {
+ formMode: 0,
+ comment: emptyComment,
+ };
- propTypes: {
+ static displayName = 'CommentForm';
+
+ static propTypes = {
ajaxSending: PropTypes.bool.isRequired,
actions: PropTypes.object.isRequired,
error: PropTypes.any,
- },
-
- getInitialState() {
- return {
- formMode: 0,
- comment: emptyComment,
- };
- },
+ };
- handleSelect(selectedKey) {
+ handleSelect = (selectedKey) => {
this.setState({ formMode: selectedKey });
- },
+ };
- handleChange() {
+ handleChange = () => {
let comment;
- // This could also be done using ReactLink:
- // http://facebook.github.io/react/docs/two-way-binding-helpers.html
if (this.state.formMode < 2) {
comment = {
author: this.refs.author.getValue(),
@@ -50,17 +46,17 @@ const CommentForm = React.createClass({
}
this.setState({ comment });
- },
+ };
- handleSubmit(e) {
+ handleSubmit = (e) => {
e.preventDefault();
const { actions } = this.props;
actions
.submitComment(this.state.comment)
.then(this.resetAndFocus);
- },
+ };
- resetAndFocus() {
+ resetAndFocus = () => {
// Don't reset a form that didn't submit, this results in data loss
if (this.props.error) return;
@@ -75,7 +71,7 @@ const CommentForm = React.createClass({
}
ref.focus();
- },
+ }
formHorizontal() {
return (
@@ -117,7 +113,7 @@ const CommentForm = React.createClass({
);
- },
+ }
formStacked() {
return (
@@ -151,7 +147,7 @@ const CommentForm = React.createClass({
);
- },
+ }
formInline() {
return (
@@ -195,7 +191,7 @@ const CommentForm = React.createClass({
);
- },
+ }
errorWarning() {
// If there is no error, there is nothing to add to the DOM
@@ -206,7 +202,7 @@ const CommentForm = React.createClass({
A server error prevented your comment from being saved. Please try again.
);
- },
+ }
render() {
let inputForm;
@@ -241,7 +237,7 @@ const CommentForm = React.createClass({
{inputForm}
);
- },
-});
+ }
+}
export default CommentForm;
diff --git a/client/app/components/CommentList.jsx b/client/app/components/CommentList.jsx
index b4321728..4b2a0d22 100644
--- a/client/app/components/CommentList.jsx
+++ b/client/app/components/CommentList.jsx
@@ -5,13 +5,13 @@ import ReactCSSTransitionGroup from 'react/lib/ReactCSSTransitionGroup';
import Comment from './Comment';
-const CommentList = React.createClass({
- displayName: 'CommentList',
+class CommentList extends React.Component {
+ static displayName = 'CommentList';
- propTypes: {
+ static propTypes = {
$$comments: PropTypes.instanceOf(Immutable.List).isRequired,
error: PropTypes.any,
- },
+ };
errorWarning() {
// If there is no error, there is nothing to add to the DOM
@@ -22,7 +22,7 @@ const CommentList = React.createClass({
A server error prevented loading comments. Please try again.
);
- },
+ }
render() {
const { $$comments } = this.props;
@@ -53,7 +53,7 @@ const CommentList = React.createClass({
);
- },
-});
+ }
+}
export default CommentList;
diff --git a/client/app/components/CommentScreen.jsx b/client/app/components/CommentScreen.jsx
index 40439789..923f2b7d 100644
--- a/client/app/components/CommentScreen.jsx
+++ b/client/app/components/CommentScreen.jsx
@@ -9,13 +9,13 @@ function select(state) {
return { data: state.$$commentsStore };
}
-const CommentScreen = React.createClass({
- displayName: 'CommentScreen',
+class CommentScreen extends React.Component {
+ static displayName = 'CommentScreen';
- propTypes: {
+ static propTypes = {
dispatch: PropTypes.func.isRequired,
data: PropTypes.object.isRequired,
- },
+ };
render() {
const { dispatch, data } = this.props;
@@ -42,8 +42,8 @@ const CommentScreen = React.createClass({
);
- },
-});
+ }
+}
// Don't forget to actually use connect!
export default connect(select)(CommentScreen);
diff --git a/client/app/components/SimpleCommentScreen.jsx b/client/app/components/SimpleCommentScreen.jsx
index 00e90233..e8b7713f 100644
--- a/client/app/components/SimpleCommentScreen.jsx
+++ b/client/app/components/SimpleCommentScreen.jsx
@@ -5,29 +5,27 @@ import CommentForm from './CommentForm';
import CommentList from './CommentList';
import metaTagsManager from '../utils/metaTagsManager';
-const SimpleCommentScreen = React.createClass({
- displayName: 'SimpleCommentScreen',
+class SimpleCommentScreen extends React.Component {
+ state = {
+ $$comments: Immutable.fromJS([]),
+ ajaxSending: false,
+ fetchCommentsError: null,
+ submitCommentError: null,
+ };
- getInitialState() {
- return {
- $$comments: Immutable.fromJS([]),
- ajaxSending: false,
- fetchCommentsError: null,
- submitCommentError: null,
- };
- },
+ static displayName = 'SimpleCommentScreen';
componentDidMount() {
this.fetchComments();
- },
+ }
fetchComments() {
return request.get('comments.json', { responseType: 'json' })
.then(res => this.setState({ $$comments: Immutable.fromJS(res.data) }))
.catch(error => this.setState({ fetchCommentsError: error }));
- },
+ }
- handleCommentSubmit(comment) {
+ handleCommentSubmit = (comment) => {
this.setState({ ajaxSending: true });
const requestConfig = {
@@ -53,7 +51,7 @@ const SimpleCommentScreen = React.createClass({
ajaxSending: false,
});
});
- },
+ };
render() {
return (
@@ -65,7 +63,7 @@ const SimpleCommentScreen = React.createClass({
);
- },
-});
+ }
+}
export default SimpleCommentScreen;
diff --git a/client/app/reducers/commentsReducer.js b/client/app/reducers/commentsReducer.js
index 5ed231b1..239b024a 100644
--- a/client/app/reducers/commentsReducer.js
+++ b/client/app/reducers/commentsReducer.js
@@ -11,7 +11,7 @@ export const $$initialState = Immutable.fromJS({
submitCommentError: null,
});
-export default function commentsReducer($$state = $$initialState, action) {
+export default function commentsReducer($$state = $$initialState, action = null) {
const { type, comment, comments, error } = action;
switch (type) {
diff --git a/client/app/startup/ClientApp.jsx b/client/app/startup/ClientApp.jsx
index b8035b7d..9f5744cc 100644
--- a/client/app/startup/ClientApp.jsx
+++ b/client/app/startup/ClientApp.jsx
@@ -6,12 +6,11 @@ import CommentScreen from '../components/CommentScreen';
const App = props => {
const store = createStore(props);
- const reactComponent = (
-
-
-
+ return (
+
+
+
);
- return reactComponent;
};
// Export is needed for the hot reload server
diff --git a/client/app/startup/ServerApp.jsx b/client/app/startup/ServerApp.jsx
index 6786a0be..612bb058 100644
--- a/client/app/startup/ServerApp.jsx
+++ b/client/app/startup/ServerApp.jsx
@@ -6,12 +6,11 @@ import CommentScreen from '../components/CommentScreen';
const App = props => {
const store = createStore(props);
- const reactComponent = (
-
-
-
+ return (
+
+
+
);
- return reactComponent;
};
export default App;
diff --git a/client/app/stores/commentsStore.js b/client/app/stores/commentsStore.js
index 0622dce7..5d1e60ac 100644
--- a/client/app/stores/commentsStore.js
+++ b/client/app/stores/commentsStore.js
@@ -17,8 +17,6 @@ export default props => {
const composedStore = compose(
applyMiddleware(thunkMiddleware, loggerMiddleware)
);
- const storeCreator = composedStore(createStore);
- const store = storeCreator(reducer, initialState);
- return store;
+ return composedStore(createStore)(reducer, initialState);
};
From 84de8d1e8b48e64796964916987fbba71674f4cf Mon Sep 17 00:00:00 2001
From: Roger Studner
Date: Mon, 2 Nov 2015 07:19:37 -0500
Subject: [PATCH 2/6] updated to constructor/bind syntax after talking with
Alex
I also renamed the "component internal non-react workflow methods" to have a leading _ per multiple best-practices guides etc.
---
client/app/components/CommentBox.jsx | 18 +++--
client/app/components/CommentForm.jsx | 68 +++++++++++--------
client/app/components/CommentList.jsx | 11 ++-
client/app/components/SimpleCommentScreen.jsx | 28 +++++---
4 files changed, 77 insertions(+), 48 deletions(-)
diff --git a/client/app/components/CommentBox.jsx b/client/app/components/CommentBox.jsx
index 9596048f..80da0185 100644
--- a/client/app/components/CommentBox.jsx
+++ b/client/app/components/CommentBox.jsx
@@ -4,6 +4,14 @@ import CommentForm from './CommentForm';
import CommentList from './CommentList';
class CommentBox extends React.Component {
+ constructor(props, context) {
+ super(props, context);
+ this.state = {};
+
+ this._ajaxCounter = this._ajaxCounter.bind(this);
+ this._isSendingAjax = this._isSendingAjax.bind(this);
+ }
+
static displayName = 'CommentBox';
static propTypes = {
pollInterval: PropTypes.number.isRequired,
@@ -17,12 +25,12 @@ class CommentBox extends React.Component {
setInterval(fetchComments, this.props.pollInterval);
}
- ajaxCounter() {
+ _ajaxCounter() {
return this.props.data.get('ajaxCounter');
}
- isSendingAjax() {
- return this.ajaxCounter() > 0;
+ _isSendingAjax() {
+ return this._ajaxCounter() > 0;
}
render() {
@@ -31,14 +39,14 @@ class CommentBox extends React.Component {
return (
- Comments { this.isSendingAjax() && `SENDING AJAX REQUEST! Ajax Counter is ${this.ajaxCounter()}` }
+ Comments { this._isSendingAjax() && `SENDING AJAX REQUEST! Ajax Counter is ${this._ajaxCounter()}` }
Text take Github Flavored Markdown. Comments older than 24 hours are deleted.
Name is preserved, Text is reset, between submits.
diff --git a/client/app/components/CommentForm.jsx b/client/app/components/CommentForm.jsx
index f0c5ae15..a3c71cce 100644
--- a/client/app/components/CommentForm.jsx
+++ b/client/app/components/CommentForm.jsx
@@ -11,10 +11,18 @@ const emptyComment = { author: '', text: '' };
const textPlaceholder = 'Say something using markdown...';
class CommentForm extends React.Component {
- state = {
- formMode: 0,
- comment: emptyComment,
- };
+ constructor(props, context) {
+ super(props, context);
+ this.state = {
+ formMode: 0,
+ comment: emptyComment,
+ };
+
+ this._handleSelect = this._handleSelect.bind(this);
+ this._handleChange = this._handleChange.bind(this);
+ this._handleSubmit = this._handleSubmit.bind(this);
+ this._resetAndFocus = this._resetAndFocus.bind(this);
+ }
static displayName = 'CommentForm';
@@ -24,11 +32,11 @@ class CommentForm extends React.Component {
error: PropTypes.any,
};
- handleSelect = (selectedKey) => {
+ _handleSelect(selectedKey) {
this.setState({ formMode: selectedKey });
- };
+ }
- handleChange = () => {
+ _handleChange() {
let comment;
if (this.state.formMode < 2) {
@@ -46,17 +54,17 @@ class CommentForm extends React.Component {
}
this.setState({ comment });
- };
+ }
- handleSubmit = (e) => {
+ _handleSubmit(e) {
e.preventDefault();
const { actions } = this.props;
actions
.submitComment(this.state.comment)
- .then(this.resetAndFocus);
- };
+ .then(this._resetAndFocus);
+ }
- resetAndFocus = () => {
+ _resetAndFocus() {
// Don't reset a form that didn't submit, this results in data loss
if (this.props.error) return;
@@ -73,11 +81,11 @@ class CommentForm extends React.Component {
ref.focus();
}
- formHorizontal() {
+ _formHorizontal() {
return (