Skip to content

Commit

Permalink
Use more ES6 syntaxes in the todomvc example
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisJamesC committed Sep 13, 2016
1 parent 4b9216b commit 27d9a24
Show file tree
Hide file tree
Showing 12 changed files with 83 additions and 133 deletions.
24 changes: 6 additions & 18 deletions examples/todomvc/src/actions/index.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,13 @@
import * as types from '../constants/ActionTypes'

export function addTodo(text) {
return { type: types.ADD_TODO, text }
}
export const addTodo = text => ({ type: types.ADD_TODO, text })

export function deleteTodo(id) {
return { type: types.DELETE_TODO, id }
}
export const deleteTodo = id => ({ type: types.DELETE_TODO, id })

export function editTodo(id, text) {
return { type: types.EDIT_TODO, id, text }
}
export const editTodo = (id, text) => ({ type: types.EDIT_TODO, id, text })

export function completeTodo(id) {
return { type: types.COMPLETE_TODO, id }
}
export const completeTodo = id => ({ type: types.COMPLETE_TODO, id })

export function completeAll() {
return { type: types.COMPLETE_ALL }
}
export const completeAll = () => ({ type: types.COMPLETE_ALL })

export function clearCompleted() {
return { type: types.CLEAR_COMPLETED }
}
export const clearCompleted = () => ({ type: types.CLEAR_COMPLETED })
26 changes: 12 additions & 14 deletions examples/todomvc/src/components/Footer.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,16 @@ const FILTER_TITLES = {
[SHOW_COMPLETED]: 'Completed'
}

class Footer extends Component {
renderTodoCount() {
export default class Footer extends Component {
static propTypes = {
completedCount: PropTypes.number.isRequired,
activeCount: PropTypes.number.isRequired,
filter: PropTypes.string.isRequired,
onClearCompleted: PropTypes.func.isRequired,
onShow: PropTypes.func.isRequired
}

renderTodoCount = () => {
const { activeCount } = this.props
const itemWord = activeCount === 1 ? 'item' : 'items'

Expand All @@ -20,7 +28,7 @@ class Footer extends Component {
)
}

renderFilterLink(filter) {
renderFilterLink = filter => {
const title = FILTER_TITLES[filter]
const { filter: selectedFilter, onShow } = this.props

Expand All @@ -33,7 +41,7 @@ class Footer extends Component {
)
}

renderClearButton() {
renderClearButton = () => {
const { completedCount, onClearCompleted } = this.props
if (completedCount > 0) {
return (
Expand Down Expand Up @@ -61,13 +69,3 @@ class Footer extends Component {
)
}
}

Footer.propTypes = {
completedCount: PropTypes.number.isRequired,
activeCount: PropTypes.number.isRequired,
filter: PropTypes.string.isRequired,
onClearCompleted: PropTypes.func.isRequired,
onShow: PropTypes.func.isRequired
}

export default Footer
11 changes: 6 additions & 5 deletions examples/todomvc/src/components/Footer.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import TestUtils from 'react-addons-test-utils'
import Footer from './Footer'
import { SHOW_ALL, SHOW_ACTIVE } from '../constants/TodoFilters'

function setup(propOverrides) {
const setup = propOverrides => {
const props = Object.assign({
completedCount: 0,
activeCount: 0,
Expand All @@ -22,14 +22,15 @@ function setup(propOverrides) {
}
}

function getTextContent(elem) {
const getTextContent = elem => {
const children = Array.isArray(elem.props.children) ?
elem.props.children : [ elem.props.children ]

return children.reduce(function concatText(out, child) {
return children.reduce((out, child) =>
// Concatenate the text
// Children are either elements or text strings
return out + (child.props ? getTextContent(child) : child)
}, '')
out + (child.props ? getTextContent(child) : child)
, '')
}

describe('components', () => {
Expand Down
16 changes: 7 additions & 9 deletions examples/todomvc/src/components/Header.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import React, { PropTypes, Component } from 'react'
import TodoTextInput from './TodoTextInput'

class Header extends Component {
handleSave(text) {
export default class Header extends Component {
static propTypes = {
addTodo: PropTypes.func.isRequired
}

handleSave = text => {
if (text.length !== 0) {
this.props.addTodo(text)
}
Expand All @@ -13,15 +17,9 @@ class Header extends Component {
<header className="header">
<h1>todos</h1>
<TodoTextInput newTodo
onSave={this.handleSave.bind(this)}
onSave={this.handleSave}
placeholder="What needs to be done?" />
</header>
)
}
}

Header.propTypes = {
addTodo: PropTypes.func.isRequired
}

export default Header
2 changes: 1 addition & 1 deletion examples/todomvc/src/components/Header.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import TestUtils from 'react-addons-test-utils'
import Header from './Header'
import TodoTextInput from './TodoTextInput'

function setup() {
const setup = () => {
const props = {
addTodo: jest.fn()
}
Expand Down
29 changes: 10 additions & 19 deletions examples/todomvc/src/components/MainSection.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,19 @@ const TODO_FILTERS = {
[SHOW_COMPLETED]: todo => todo.completed
}

class MainSection extends Component {
constructor(props, context) {
super(props, context)
this.state = { filter: SHOW_ALL }
export default class MainSection extends Component {
static propTypes = {
todos: PropTypes.array.isRequired,
actions: PropTypes.object.isRequired
}

handleClearCompleted() {
this.props.actions.clearCompleted()
}
state = { filter: SHOW_ALL }

handleShow(filter) {
this.setState({ filter })
}
handleClearCompleted = () => this.props.actions.clearCompleted()

handleShow = filter => this.setState({ filter })

renderToggleAll(completedCount) {
renderToggleAll = completedCount => {
const { todos, actions } = this.props
if (todos.length > 0) {
return (
Expand All @@ -35,7 +33,7 @@ class MainSection extends Component {
}
}

renderFooter(completedCount) {
renderFooter = completedCount => {
const { todos } = this.props
const { filter } = this.state
const activeCount = todos.length - completedCount
Expand Down Expand Up @@ -74,10 +72,3 @@ class MainSection extends Component {
)
}
}

MainSection.propTypes = {
todos: PropTypes.array.isRequired,
actions: PropTypes.object.isRequired
}

export default MainSection
2 changes: 1 addition & 1 deletion examples/todomvc/src/components/MainSection.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import TodoItem from './TodoItem'
import Footer from './Footer'
import { SHOW_ALL, SHOW_COMPLETED } from '../constants/TodoFilters'

function setup(propOverrides) {
const setup = propOverrides => {
const props = Object.assign({
todos: [
{
Expand Down
31 changes: 12 additions & 19 deletions examples/todomvc/src/components/TodoItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,21 @@ import React, { Component, PropTypes } from 'react'
import classnames from 'classnames'
import TodoTextInput from './TodoTextInput'

class TodoItem extends Component {
constructor(props, context) {
super(props, context)
this.state = {
editing: false
}
export default class TodoItem extends Component {
static propTypes = {
todo: PropTypes.object.isRequired,
editTodo: PropTypes.func.isRequired,
deleteTodo: PropTypes.func.isRequired,
completeTodo: PropTypes.func.isRequired
}

handleDoubleClick() {
this.setState({ editing: true })
state = {
editing: false
}

handleSave(id, text) {
handleDoubleClick = () => this.setState({ editing: true })

handleSave = (id, text) => {
if (text.length === 0) {
this.props.deleteTodo(id)
} else {
Expand All @@ -40,7 +42,7 @@ class TodoItem extends Component {
type="checkbox"
checked={todo.completed}
onChange={() => completeTodo(todo.id)} />
<label onDoubleClick={this.handleDoubleClick.bind(this)}>
<label onDoubleClick={this.handleDoubleClick}>
{todo.text}
</label>
<button className="destroy"
Expand All @@ -59,12 +61,3 @@ class TodoItem extends Component {
)
}
}

TodoItem.propTypes = {
todo: PropTypes.object.isRequired,
editTodo: PropTypes.func.isRequired,
deleteTodo: PropTypes.func.isRequired,
completeTodo: PropTypes.func.isRequired
}

export default TodoItem
2 changes: 1 addition & 1 deletion examples/todomvc/src/components/TodoItem.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import TestUtils from 'react-addons-test-utils'
import TodoItem from './TodoItem'
import TodoTextInput from './TodoTextInput'

function setup( editing = false ) {
const setup = ( editing = false ) => {
const props = {
todo: {
id: 0,
Expand Down
42 changes: 18 additions & 24 deletions examples/todomvc/src/components/TodoTextInput.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import React, { Component, PropTypes } from 'react'
import classnames from 'classnames'

class TodoTextInput extends Component {
constructor(props, context) {
super(props, context)
this.state = {
text: this.props.text || ''
}
export default class TodoTextInput extends Component {
static propTypes = {
onSave: PropTypes.func.isRequired,
text: PropTypes.string,
placeholder: PropTypes.string,
editing: PropTypes.bool,
newTodo: PropTypes.bool
}

state = {
text: this.props.text || ''
}

handleSubmit(e) {
handleSubmit = e => {
const text = e.target.value.trim()
if (e.which === 13) {
this.props.onSave(text)
Expand All @@ -19,11 +24,10 @@ class TodoTextInput extends Component {
}
}

handleChange(e) {
this.setState({ text: e.target.value })
}
handleChange = e => this.setState({ text: e.target.value })

handleBlur(e) {

handleBlur = e => {
if (!this.props.newTodo) {
this.props.onSave(e.target.value)
}
Expand All @@ -40,19 +44,9 @@ class TodoTextInput extends Component {
placeholder={this.props.placeholder}
autoFocus="true"
value={this.state.text}
onBlur={this.handleBlur.bind(this)}
onChange={this.handleChange.bind(this)}
onKeyDown={this.handleSubmit.bind(this)} />
onBlur={this.handleBlur}
onChange={this.handleChange}
onKeyDown={this.handleSubmit} />
)
}
}

TodoTextInput.propTypes = {
onSave: PropTypes.func.isRequired,
text: PropTypes.string,
placeholder: PropTypes.string,
editing: PropTypes.bool,
newTodo: PropTypes.bool
}

export default TodoTextInput
2 changes: 1 addition & 1 deletion examples/todomvc/src/components/TodoTextInput.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react'
import TestUtils from 'react-addons-test-utils'
import TodoTextInput from './TodoTextInput'

function setup(propOverrides) {
const setup = propOverrides => {
const props = Object.assign({
onSave: jest.fn(),
text: 'Use Redux',
Expand Down
29 changes: 8 additions & 21 deletions examples/todomvc/src/containers/App.js
Original file line number Diff line number Diff line change
@@ -1,38 +1,25 @@
import React, { Component, PropTypes } from 'react'
import React, { PropTypes } from 'react'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import Header from '../components/Header'
import MainSection from '../components/MainSection'
import * as TodoActions from '../actions'

class App extends Component {
render() {
const { todos, actions } = this.props
return (
<div>
<Header addTodo={actions.addTodo} />
<MainSection todos={todos} actions={actions} />
</div>
)
}
}
const App = ({todos, actions}) => <div>
<Header addTodo={actions.addTodo} />
<MainSection todos={todos} actions={actions} />
</div>

App.propTypes = {
todos: PropTypes.array.isRequired,
actions: PropTypes.object.isRequired
}

function mapStateToProps(state) {
return {
todos: state.todos
}
}
const mapStateToProps = state => ({todos: state.todos})

function mapDispatchToProps(dispatch) {
return {
const mapDispatchToProps = dispatch => ({
actions: bindActionCreators(TodoActions, dispatch)
}
}
})

export default connect(
mapStateToProps,
Expand Down

0 comments on commit 27d9a24

Please sign in to comment.