Skip to content

Commit a589d68

Browse files
committed
[todos] [refactor] improve the general style of the approach to React
1 parent 55e77e8 commit a589d68

File tree

11 files changed

+92
-144
lines changed

11 files changed

+92
-144
lines changed

docs/basics/ExampleTodoList.md

Lines changed: 55 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ import React from 'react'
1111
import { render } from 'react-dom'
1212
import { Provider } from 'react-redux'
1313
import { createStore } from 'redux'
14-
import todoApp from './reducers'
14+
import reducer from './reducers'
1515
import App from './components/App'
1616

17-
let store = createStore(todoApp)
17+
const store = createStore(reducer)
1818

1919
render(
2020
<Provider store={store}>
@@ -30,27 +30,21 @@ render(
3030

3131
```js
3232
let nextTodoId = 0
33-
export const addTodo = text => {
34-
return {
35-
type: 'ADD_TODO',
36-
id: nextTodoId++,
37-
text
38-
}
39-
}
33+
export const addTodo = text => ({
34+
type: 'ADD_TODO',
35+
id: nextTodoId++,
36+
text
37+
})
4038

41-
export const setVisibilityFilter = filter => {
42-
return {
43-
type: 'SET_VISIBILITY_FILTER',
44-
filter
45-
}
46-
}
39+
export const setVisibilityFilter = filter => ({
40+
type: 'SET_VISIBILITY_FILTER',
41+
filter
42+
})
4743

48-
export const toggleTodo = id => {
49-
return {
50-
type: 'TOGGLE_TODO',
51-
id
52-
}
53-
}
44+
export const toggleTodo = id => ({
45+
type: 'TOGGLE_TODO',
46+
id
47+
})
5448

5549
export const VisibilityFilters = {
5650
SHOW_ALL: 'SHOW_ALL',
@@ -154,11 +148,15 @@ import React from 'react'
154148
import PropTypes from 'prop-types'
155149
import Todo from './Todo'
156150

157-
const TodoList = ({ todos, onTodoClick }) => (
151+
const TodoList = ({ todos, toggleTodo }) => (
158152
<ul>
159-
{todos.map(todo => (
160-
<Todo key={todo.id} {...todo} onClick={() => onTodoClick(todo.id)} />
161-
))}
153+
{todos.map(todo =>
154+
<Todo
155+
key={todo.id}
156+
{...todo}
157+
onClick={() => toggleTodo(todo.id)}
158+
/>
159+
)}
162160
</ul>
163161
)
164162

@@ -170,7 +168,7 @@ TodoList.propTypes = {
170168
text: PropTypes.string.isRequired
171169
}).isRequired
172170
).isRequired,
173-
onTodoClick: PropTypes.func.isRequired
171+
toggleTodo: PropTypes.func.isRequired
174172
}
175173

176174
export default TodoList
@@ -181,23 +179,17 @@ export default TodoList
181179
import React from 'react'
182180
import PropTypes from 'prop-types'
183181

184-
const Link = ({ active, children, onClick }) => {
185-
if (active) {
186-
return <span>{children}</span>
187-
}
188-
189-
return (
190-
<a
191-
href=""
192-
onClick={e => {
193-
e.preventDefault()
194-
onClick()
195-
}}
196-
>
197-
{children}
198-
</a>
199-
)
200-
}
182+
const Link = ({ active, children, onClick }) => (
183+
<button
184+
onClick={onClick}
185+
disabled={active}
186+
style={{
187+
marginLeft: '4px',
188+
}}
189+
>
190+
{children}
191+
</button>
192+
)
201193

202194
Link.propTypes = {
203195
active: PropTypes.bool.isRequired,
@@ -216,21 +208,18 @@ import FilterLink from '../containers/FilterLink'
216208
import { VisibilityFilters } from '../actions'
217209

218210
const Footer = () => (
219-
<p>
220-
Show:
221-
{' '}
211+
<div>
212+
<span>Show: </span>
222213
<FilterLink filter={VisibilityFilters.SHOW_ALL}>
223214
All
224215
</FilterLink>
225-
{', '}
226216
<FilterLink filter={VisibilityFilters.SHOW_ACTIVE}>
227217
Active
228218
</FilterLink>
229-
{', '}
230219
<FilterLink filter={VisibilityFilters.SHOW_COMPLETED}>
231220
Completed
232221
</FilterLink>
233-
</p>
222+
</div>
234223
)
235224

236225
export default Footer
@@ -276,26 +265,18 @@ const getVisibleTodos = (todos, filter) => {
276265
}
277266
}
278267

279-
const mapStateToProps = state => {
280-
return {
281-
todos: getVisibleTodos(state.todos, state.visibilityFilter)
282-
}
283-
}
268+
const mapStateToProps = state => ({
269+
todos: getVisibleTodos(state.todos, state.visibilityFilter)
270+
})
284271

285-
const mapDispatchToProps = dispatch => {
286-
return {
287-
onTodoClick: id => {
288-
dispatch(toggleTodo(id))
289-
}
290-
}
291-
}
272+
const mapDispatchToProps = dispatch => ({
273+
toggleTodo: id => dispatch(toggleTodo(id))
274+
})
292275

293-
const VisibleTodoList = connect(
276+
export default connect(
294277
mapStateToProps,
295278
mapDispatchToProps
296279
)(TodoList)
297-
298-
export default VisibleTodoList
299280
```
300281

301282
#### `containers/FilterLink.js`
@@ -305,26 +286,18 @@ import { connect } from 'react-redux'
305286
import { setVisibilityFilter } from '../actions'
306287
import Link from '../components/Link'
307288

308-
const mapStateToProps = (state, ownProps) => {
309-
return {
310-
active: ownProps.filter === state.visibilityFilter
311-
}
312-
}
289+
const mapStateToProps = (state, ownProps) => ({
290+
active: ownProps.filter === state.visibilityFilter
291+
})
313292

314-
const mapDispatchToProps = (dispatch, ownProps) => {
315-
return {
316-
onClick: () => {
317-
dispatch(setVisibilityFilter(ownProps.filter))
318-
}
319-
}
320-
}
293+
const mapDispatchToProps = (dispatch, ownProps) => ({
294+
onClick: () => dispatch(setVisibilityFilter(ownProps.filter))
295+
})
321296

322-
const FilterLink = connect(
297+
export default connect(
323298
mapStateToProps,
324299
mapDispatchToProps
325300
)(Link)
326-
327-
export default FilterLink
328301
```
329302

330303
### Other Components
@@ -336,7 +309,7 @@ import React from 'react'
336309
import { connect } from 'react-redux'
337310
import { addTodo } from '../actions'
338311

339-
let AddTodo = ({ dispatch }) => {
312+
const AddTodo = ({ dispatch }) => {
340313
let input
341314

342315
return (
@@ -351,19 +324,14 @@ let AddTodo = ({ dispatch }) => {
351324
input.value = ''
352325
}}
353326
>
354-
<input
355-
ref={node => {
356-
input = node
357-
}}
358-
/>
327+
<input ref={node => input = node} />
359328
<button type="submit">
360329
Add Todo
361330
</button>
362331
</form>
363332
</div>
364333
)
365334
}
366-
AddTodo = connect()(AddTodo)
367335

368-
export default AddTodo
336+
export default connect()(AddTodo)
369337
```
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
let nextTodoId = 0
2-
export const addTodo = (text) => ({
2+
export const addTodo = text => ({
33
type: 'ADD_TODO',
44
id: nextTodoId++,
55
text
66
})
77

8-
export const setVisibilityFilter = (filter) => ({
8+
export const setVisibilityFilter = filter => ({
99
type: 'SET_VISIBILITY_FILTER',
1010
filter
1111
})
1212

13-
export const toggleTodo = (id) => ({
13+
export const toggleTodo = id => ({
1414
type: 'TOGGLE_TODO',
1515
id
1616
})
1717

1818
export const VisibilityFilters = {
19-
SHOW_ALL: 'SHOW_ALL',
20-
SHOW_COMPLETED: 'SHOW_COMPLETED',
21-
SHOW_ACTIVE: 'SHOW_ACTIVE'
19+
SHOW_ALL: 'SHOW_ALL',
20+
SHOW_COMPLETED: 'SHOW_COMPLETED',
21+
SHOW_ACTIVE: 'SHOW_ACTIVE'
2222
}

examples/todos/src/components/Footer.js

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,18 @@ import FilterLink from '../containers/FilterLink'
33
import { VisibilityFilters } from '../actions'
44

55
const Footer = () => (
6-
<p>
7-
Show:
8-
{" "}
9-
<FilterLink filter={ VisibilityFilters.SHOW_ALL }>
6+
<div>
7+
<span>Show: </span>
8+
<FilterLink filter={VisibilityFilters.SHOW_ALL}>
109
All
1110
</FilterLink>
12-
{", "}
13-
<FilterLink filter={ VisibilityFilters.SHOW_ACTIVE }>
11+
<FilterLink filter={VisibilityFilters.SHOW_ACTIVE}>
1412
Active
1513
</FilterLink>
16-
{", "}
17-
<FilterLink filter={ VisibilityFilters.SHOW_COMPLETED }>
14+
<FilterLink filter={VisibilityFilters.SHOW_COMPLETED}>
1815
Completed
1916
</FilterLink>
20-
</p>
17+
</div>
2118
)
2219

2320
export default Footer

examples/todos/src/components/Link.js

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,17 @@
11
import React from 'react'
22
import PropTypes from 'prop-types'
33

4-
const Link = ({ active, children, onClick }) => {
5-
if (active) {
6-
return <span>{children}</span>
7-
}
8-
9-
return (
10-
// eslint-disable-next-line
11-
<a href="#"
12-
onClick={e => {
13-
e.preventDefault()
14-
onClick()
4+
const Link = ({ active, children, onClick }) => (
5+
<button
6+
onClick={onClick}
7+
disabled={active}
8+
style={{
9+
marginLeft: '4px',
1510
}}
1611
>
1712
{children}
18-
</a>
19-
)
20-
}
13+
</button>
14+
)
2115

2216
Link.propTypes = {
2317
active: PropTypes.bool.isRequired,

examples/todos/src/components/TodoList.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ import React from 'react'
22
import PropTypes from 'prop-types'
33
import Todo from './Todo'
44

5-
const TodoList = ({ todos, onTodoClick }) => (
5+
const TodoList = ({ todos, toggleTodo }) => (
66
<ul>
77
{todos.map(todo =>
88
<Todo
99
key={todo.id}
1010
{...todo}
11-
onClick={() => onTodoClick(todo.id)}
11+
onClick={() => toggleTodo(todo.id)}
1212
/>
1313
)}
1414
</ul>
@@ -20,7 +20,7 @@ TodoList.propTypes = {
2020
completed: PropTypes.bool.isRequired,
2121
text: PropTypes.string.isRequired
2222
}).isRequired).isRequired,
23-
onTodoClick: PropTypes.func.isRequired
23+
toggleTodo: PropTypes.func.isRequired
2424
}
2525

2626
export default TodoList

examples/todos/src/containers/AddTodo.js

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React from 'react'
22
import { connect } from 'react-redux'
33
import { addTodo } from '../actions'
44

5-
let AddTodo = ({ dispatch }) => {
5+
const AddTodo = ({ dispatch }) => {
66
let input
77

88
return (
@@ -15,16 +15,13 @@ let AddTodo = ({ dispatch }) => {
1515
dispatch(addTodo(input.value))
1616
input.value = ''
1717
}}>
18-
<input ref={node => {
19-
input = node
20-
}} />
18+
<input ref={node => input = node} />
2119
<button type="submit">
2220
Add Todo
2321
</button>
2422
</form>
2523
</div>
2624
)
2725
}
28-
AddTodo = connect()(AddTodo)
2926

30-
export default AddTodo
27+
export default connect()(AddTodo)

0 commit comments

Comments
 (0)