Skip to content

Commit

Permalink
feat(core): React.PureComponent generators (react-boilerplate#811)
Browse files Browse the repository at this point in the history
* feat(react): use React.PureComponent in demo app

* feat(internals): generator support for PureComponent

* chore(eslint): add missing eslint-disable on HomePage

* Update appveyor.yml

* Update appveyor.yml
  • Loading branch information
justingreenberg authored and mxstbr committed Nov 2, 2016
1 parent a37c3e6 commit f719214
Show file tree
Hide file tree
Showing 12 changed files with 70 additions and 13 deletions.
2 changes: 1 addition & 1 deletion app/containers/HomePage/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { changeUsername } from './actions';
import { selectUsername } from './selectors';
import { selectRepos, selectLoading, selectError } from 'containers/App/selectors';

export class HomePage extends React.Component {
export class HomePage extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function
/**
* when initial state username is not null, submit the form to load repos
*/
Expand Down
2 changes: 1 addition & 1 deletion app/containers/LanguageProvider/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { createSelector } from 'reselect';
import { IntlProvider } from 'react-intl';
import { selectLocale } from './selectors';

export class LanguageProvider extends React.Component { // eslint-disable-line react/prefer-stateless-function
export class LanguageProvider extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function
render() {
return (
<IntlProvider locale={this.props.locale} key={this.props.locale} messages={this.props.messages[this.props.locale]}>
Expand Down
2 changes: 1 addition & 1 deletion app/containers/LocaleToggle/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { appLocales } from '../../i18n';
import { changeLocale } from '../LanguageProvider/actions';
import { selectLocale } from '../LanguageProvider/selectors';

export class LocaleToggle extends React.Component { // eslint-disable-line
export class LocaleToggle extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function
render() {
return (
<Wrapper>
Expand Down
2 changes: 1 addition & 1 deletion app/containers/RepoListItem/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import RepoLink from './RepoLink';
import Wrapper from './Wrapper';
import { selectCurrentUser } from 'containers/App/selectors';

export class RepoListItem extends React.Component { // eslint-disable-line react/prefer-stateless-function
export class RepoListItem extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function
render() {
const item = this.props.item;
let nameprefix = '';
Expand Down
33 changes: 33 additions & 0 deletions internals/generators/component/es6.pure.js.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
*
* {{ properCase name }}
*
*/

import React from 'react';

{{#if wantMessages}}
import { FormattedMessage } from 'react-intl';
import messages from './messages';
{{/if}}
{{#if wantCSS}}
import styles from './styles.css';
{{/if}}

class {{ properCase name }} extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function
render() {
return (
{{#if wantCSS}}
<div className={{curly true}}styles.{{ camelCase name }}{{curly}}>
{{else}}
<div>
{{/if}}
{{#if wantMessages}}
<FormattedMessage {...messages.header} />
{{/if}}
</div>
);
}
}

export default {{ properCase name }};
24 changes: 22 additions & 2 deletions internals/generators/component/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ module.exports = {
name: 'type',
message: 'Select the type of component',
default: 'Stateless Function',
choices: () => ['ES6 Class', 'Stateless Function'],
choices: () => ['Stateless Function', 'ES6 Class (Pure)', 'ES6 Class'],
}, {
type: 'input',
name: 'name',
Expand All @@ -32,10 +32,30 @@ module.exports = {
}],
actions: (data) => {
// Generate index.js and index.test.js
let componentTemplate;

switch (data.type) {
case 'ES6 Class': {
componentTemplate = './component/es6.js.hbs';
break;
}
case 'ES6 Class (Pure)': {
componentTemplate = './component/es6.pure.js.hbs';
break;
}
case 'Stateless Function': {
componentTemplate = './component/stateless.js.hbs';
break;
}
default: {
componentTemplate = './component/es6.js.hbs';
}
}

const actions = [{
type: 'add',
path: '../../app/components/{{properCase name}}/index.js',
templateFile: data.type === 'ES6 Class' ? './component/es6.js.hbs' : './component/stateless.js.hbs',
templateFile: componentTemplate,
abortOnFail: true,
}, {
type: 'add',
Expand Down
6 changes: 6 additions & 0 deletions internals/generators/container/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ module.exports = {

return 'The name is required';
},
}, {
type: 'list',
name: 'component',
message: 'Select a base component:',
default: 'PureComponent',
choices: () => ['PureComponent', 'Component'],
}, {
type: 'confirm',
name: 'wantHeaders',
Expand Down
2 changes: 1 addition & 1 deletion internals/generators/container/index.js.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import messages from './messages';
import styles from './styles.css';
{{/if}}

export class {{ properCase name }} extends React.Component { // eslint-disable-line react/prefer-stateless-function
export class {{ properCase name }} extends React.{{{ component }}} { // eslint-disable-line react/prefer-stateless-function
render() {
return (
{{#if wantCSS}}
Expand Down
2 changes: 1 addition & 1 deletion internals/templates/appContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

import React from 'react';

export default class App extends React.Component { // eslint-disable-line react/prefer-stateless-function
export default class App extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function

static propTypes = {
children: React.PropTypes.node,
Expand Down
3 changes: 1 addition & 2 deletions internals/templates/homePage/homePage.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ import React from 'react';
import { FormattedMessage } from 'react-intl';
import messages from './messages';

export default class HomePage extends React.Component { // eslint-disable-line react/prefer-stateless-function

export default class HomePage extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function
render() {
return (
<h1>
Expand Down
2 changes: 1 addition & 1 deletion internals/templates/languageProvider/languageProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { createSelector } from 'reselect';
import { IntlProvider } from 'react-intl';
import { selectLocale } from './selectors';

export class LanguageProvider extends React.Component { // eslint-disable-line react/prefer-stateless-function
export class LanguageProvider extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function
render() {
return (
<IntlProvider locale={this.props.locale} key={this.props.locale} messages={this.props.messages[this.props.locale]}>
Expand Down
3 changes: 1 addition & 2 deletions internals/templates/notFoundPage/notFoundPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ import React from 'react';
import { FormattedMessage } from 'react-intl';
import messages from './messages';

export default class NotFound extends React.Component { // eslint-disable-line react/prefer-stateless-function

export default class NotFound extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function
render() {
return (
<h1>
Expand Down

0 comments on commit f719214

Please sign in to comment.