Skip to content

Commit

Permalink
use redux instead of state
Browse files Browse the repository at this point in the history
  • Loading branch information
Shek Hang Ng authored and Shek Hang Ng committed Nov 6, 2021
1 parent 24d506f commit 9b2787f
Show file tree
Hide file tree
Showing 11 changed files with 109 additions and 53 deletions.
22 changes: 22 additions & 0 deletions src/actions/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
let nextTodoId = 0
export const addTodo = text => ({
type: 'ADD_TODO',
id: nextTodoId++,
text
})

export const setVisibilityFilter = filter => ({
type: 'SET_VISIBILITY_FILTER',
filter
})

export const toggleTodo = id => ({
type: 'TOGGLE_TODO',
id
})

export const VisibilityFilters = {
ALL: "ALL",
ACTIVE: "ACTIVE",
COMPLETED: "COMPLETED"
}
31 changes: 4 additions & 27 deletions src/app.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,14 @@
import React, {useState} from 'react'
import React from 'react'
import TodoAdd from './components/TodoAdd'
import TodoList from './components/TodoList'
import TodoFilter from './components/TodoFilter'
import {Status} from './utils/constant'

const App = (props) => {
const [todos, setTodos] = useState([
{
id: 0,
text: "task 1",
completed: false
}
])

const [filter, setFilter] = useState(Status.ALL)

function handleAddTodo(text) {
setTodos([...todos, {id: todos.length, text:text, completed:false}]);
}

function handleFilter(status) {
setFilter(status)
}

function handleComplete(id) {
setTodos(todos.map(val => (val.id === id) ? {...val, completed: !val.completed} : val))
}

return (
<div>
<TodoAdd onAddTodo={handleAddTodo} />
<TodoList todos={todos} filter={filter} onComplete={handleComplete} />
<TodoFilter onFilter={handleFilter} />
<TodoAdd/>
<TodoList />
<TodoFilter />
</div>
)
}
Expand Down
8 changes: 5 additions & 3 deletions src/components/Todo.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import React from 'react'
import {toggleTodo} from '../actions'
import {connect} from 'react-redux'

const Todo = ({id, text, completed, onComplete}) => (
const Todo = ({id, text, completed, dispatch}) => (
<li
onClick={()=>onComplete(id)}
onClick={()=>dispatch(toggleTodo(id))}
style={{
textDecoration: completed ? 'line-through': 'none'
}}
Expand All @@ -11,4 +13,4 @@ const Todo = ({id, text, completed, onComplete}) => (
</li>
)

export default Todo
export default connect()(Todo)
10 changes: 6 additions & 4 deletions src/components/TodoAdd.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React from 'react'
import { connect } from 'react-redux'
import { addTodo } from '../actions'

const TodoAdd = ({onAddTodo}) => {
const TodoAdd = ({dispatch}) => {
let input

const handleSubmit = (e) => {
Expand All @@ -9,8 +11,8 @@ const TodoAdd = ({onAddTodo}) => {
return
}

onAddTodo(input.value)
input.value = "";
dispatch(addTodo(input.value))
input.value = ''
}

return (
Expand All @@ -23,4 +25,4 @@ const TodoAdd = ({onAddTodo}) => {
)
}

export default TodoAdd
export default connect()(TodoAdd)
13 changes: 7 additions & 6 deletions src/components/TodoFilter.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import React from 'react'
import {Status} from '../utils/constant'
import {VisibilityFilters, setVisibilityFilter} from '../actions'
import {connect} from 'react-redux'

const TodoFilter = ({onFilter}) => (
const TodoFilter = ({dispatch}) => (
<div>
Show {' '}
<button onClick={()=>onFilter(Status.ALL)}>All</button>{' '}
<button onClick={()=>onFilter(Status.ACTIVE)}>Active</button>{' '}
<button onClick={()=>onFilter(Status.COMPLETED)}>Completed</button>
<button onClick={()=>dispatch(setVisibilityFilter(VisibilityFilters.ALL))}>All</button>{' '}
<button onClick={()=>dispatch(setVisibilityFilter(VisibilityFilters.ACTIVE))}>Active</button>{' '}
<button onClick={()=>dispatch(setVisibilityFilter(VisibilityFilters.COMPLETED))}>Completed</button>
</div>
)

export default TodoFilter
export default connect()(TodoFilter)
21 changes: 14 additions & 7 deletions src/components/TodoList.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,31 @@
import React from 'react'
import Todo from './Todo'
import {Status} from '../utils/constant'
import {VisibilityFilters} from '../actions'
import { connect } from 'react-redux'

const getFilterTodos = (todos, filter) => {
switch(filter) {
case Status.ALL:
case VisibilityFilters.ALL:
return todos;
case Status.ACTIVE:
case VisibilityFilters.ACTIVE:
return todos.filter(val => !val.completed)
case Status.COMPLETED:
case VisibilityFilters.COMPLETED:
return todos.filter(val => val.completed)
default:
throw new Error('Unknown filter: ' + filter)
}
}

const TodoList = ({todos, filter, onComplete}) => (
const mapStateToProps = state => ({
todos: getFilterTodos(state.todos, state.visibilityFilter)
})

const TodoList = ({todos}) => (
<ul>
{ getFilterTodos(todos, filter).map(todo => <Todo key={todo.id} onComplete={onComplete} {...todo} />) }
{ todos.map(todo => <Todo key={todo.id} {...todo} />) }
</ul>
)

export default TodoList
export default connect(
mapStateToProps
)(TodoList)
9 changes: 8 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import React from 'react'
import ReactDOM from 'react-dom'
import App from './app'
import {createStore} from 'redux'
import {Provider} from 'react-redux'
import rootReducer from './reducers'

const store = createStore(rootReducer)

ReactDOM.render(
<App/>,
<Provider store={store}>
<App/>
</Provider>,
document.getElementById('root')
)
8 changes: 8 additions & 0 deletions src/reducers/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { combineReducers } from 'redux'
import todos from './todos'
import visibilityFilter from './visibilityFilter'

export default combineReducers({
todos,
visibilityFilter
})
23 changes: 23 additions & 0 deletions src/reducers/todos.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const todos = (state = [{id:0, text:'task1', completed:false}], action) => {
switch (action.type) {
case 'ADD_TODO':
return [
...state,
{
id: action.id,
text: action.text,
completed: false
}
]
case 'TOGGLE_TODO':
return state.map(todo =>
(todo.id === action.id) ?
{...todo, completed: !todo.completed} :
todo
)
default:
return state
}
}

export default todos
12 changes: 12 additions & 0 deletions src/reducers/visibilityFilter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { VisibilityFilters } from '../actions'

const visibilityFilter = (state = VisibilityFilters.ALL, action) => {
switch (action.type) {
case 'SET_VISIBILITY_FILTER':
return action.filter
default:
return state
}
}

export default visibilityFilter
5 changes: 0 additions & 5 deletions src/utils/constant.js

This file was deleted.

0 comments on commit 9b2787f

Please sign in to comment.