Skip to content

Instantly share code, notes, and snippets.

@yashikagarg13
Forked from anonymous/index.html
Last active March 20, 2017 12:42
Show Gist options
  • Save yashikagarg13/bc97f0f2f9788478c0f2cd14b810cde8 to your computer and use it in GitHub Desktop.
Save yashikagarg13/bc97f0f2f9788478c0f2cd14b810cde8 to your computer and use it in GitHub Desktop.
ToDo App - Separate Action creators. source https://jsbin.com/nexumip
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<script src="https://unpkg.com/react@15/dist/react.js"></script>
<script src="https://unpkg.com/react-dom@15/dist/react-dom.js"></script>
<script src="https://wzrd.in/standalone/deep-freeze@latest"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/3.6.0/redux.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/5.0.3/react-redux.js"></script>
</head>
<body>
<div id="app"></div>
<script id="jsbin-javascript">
// Reducers
const todoReducer = (state = {}, action) => {
switch(action.type) {
case "ADD_TODO":
return {...action.todo, completed: false};
case "TOGGLE_TODO":
if (state.id !== action.id) {
return state;
}
return {
...state,
completed: !state.completed
}
default:
return state;
}
}
const todosReducer = (state = [], action) => {
switch(action.type) {
case "ADD_TODO":
return [...state, todoReducer(undefined, action)];
case "TOGGLE_TODO":
return state.map(todo => todoReducer(todo, action));
default:
return state;
}
}
const visbilityFilterReducer = (state = "SHOW_ALL", action) => {
switch(action.type) {
case "SET_VISIBILITY_FILTER":
return action.filter;
default:
return state;
}
}
const {combineReducers} = Redux;
const todoAppReducer = combineReducers({
todos: todosReducer,
visbilityFilter: visbilityFilterReducer,
});
// Helper Function
const getVisibleTodos = (todos, filter) => {
switch(filter) {
case "SHOW_ALL":
return todos;
case "SHOW_ACTIVE":
return todos.filter(t => !t.completed);
case "SHOW_COMPLETED":
return todos.filter(t => t.completed);
default:
return todos;
}
}
// Action Creators
let nextTodoId = 0;
const addTodo = (text) => {
return {
type: "ADD_TODO",
text,
id: ++nextTodoId;
}
}
const toggleTodo = (id) => {
return {
type: "TOGGLE_TODO",
id,
};
}
const setVisibilityFilter = (filter) => {
return {
type: "SET_VISIBILITY_FILTER",
filter: filter
};
}
// Components
const {Component} = React;
const {connect} = ReactRedux;
const Link = ({
active,
onClick,
children
}) => {
return active
? <span>{children}</span>
: <a href= "#"
onClick={e => {
e.preventDefault();
onClick();
}
}>
{children}
</a>
};
const mapStateToPropsFilterLink = (state, ownProps) => {
return {
active: ownProps.filter === state.visbilityFilter,
};
}
const mapDispatchToPropsFilterLink = (dispatch, ownProps) => {
return {
onClick: () => {
dispatch(setVisibilityFilter(ownProps.filter))
}
};
}
const FilterLink = connect(
mapStateToPropsFilterLink,
mapDispatchToPropsFilterLink,
)(Link);
const Footer = () => {
return (
<p>Show: &nbsp;&nbsp;
<FilterLink filter="SHOW_ALL">
All</FilterLink>&nbsp;&nbsp;
<FilterLink filter="SHOW_ACTIVE">
Active</FilterLink>&nbsp;&nbsp;
<FilterLink filter="SHOW_COMPLETED">
Completed</FilterLink>
</p>
);
}
const ToDo = ({id, text, completed, toggleTodo}) => {
const completedStyle = {
textDecoration: "line-through",
};
return (
<li onClick={toggleTodo.bind(null, id)}
style={completed ? completedStyle : null }>
{text}</li>
);
}
const ToDoList = ({todos, toggleTodo}) => {
return (
<ul>
{todos.map(todo =>
<ToDo
key={todo.id}
{...todo}
toggleTodo={toggleTodo} />
)}
</ul>
);
}
// This component is neither presentational nor container.
// This is kept along with behaviour because we can not break down further.
// SECOND param is context if we specify contextTypes.
let AddTodo = ({dispatch}) => {
let input;
return (
<div>
<input type="text" ref={node => {input = node;}} />
<button type="button"
onClick={() => {
dispatch(addTodo(input.value));
input.value = "";
}}>Submit</button>
</div>
);
}
// // SPECIFYING contextTypes IS A MUST to use context feature
// AddTodo.contextTypes = {
// store: React.PropTypes.object,
// };
AddTodo = connect(
// null, // There is no need to subscribe to this store, so we are passing mapStateToProps as null
// null, // If we pass null or falsy value to second param, connect will pass 'dispatch' by default as prop to the component
// So we can go without passing any thing to conenct function
// if we don't want component to subscribe t store changes
// as well as when component only needs to access dispatch function as props.
)(AddTodo);
const mapStateToProps = (state) => {
return {
todos: getVisibleTodos(state.todos, state.visbilityFilter),
};
}
const mapDispatchToProps = (dispatch) => {
return {
toggleTodo: id => {
dispatch(toggleTodo(id));
}
};
}
const VisibleTodoList = connect(
mapStateToProps,
mapDispatchToProps,
)(ToDoList);
const TodoApp = () => {
return (
<div>
<AddTodo />
<VisibleTodoList />
<Footer />
</div>
);
}
// class Provider extends Component {
// getChildContext () {
// return {
// store: this.props.store,
// };
// }
// render () {
// return this.props.children;
// }
// }
// // SPECIFYING childContextTypes IS A MUST to use context feature
// Provider.childContextTypes = {
// store: React.PropTypes.object,
// };
const {createStore} = Redux;
const {Provider} = ReactRedux;
ReactDOM.render(
<Provider store={createStore(todoAppReducer)}>
<TodoApp/>
</Provider>,
document.getElementById("app"));
</script>
<script id="jsbin-source-javascript" type="text/javascript">// Reducers
const todoReducer = (state = {}, action) => {
switch(action.type) {
case "ADD_TODO":
return {...action.todo, completed: false};
case "TOGGLE_TODO":
if (state.id !== action.id) {
return state;
}
return {
...state,
completed: !state.completed
}
default:
return state;
}
}
const todosReducer = (state = [], action) => {
switch(action.type) {
case "ADD_TODO":
return [...state, todoReducer(undefined, action)];
case "TOGGLE_TODO":
return state.map(todo => todoReducer(todo, action));
default:
return state;
}
}
const visbilityFilterReducer = (state = "SHOW_ALL", action) => {
switch(action.type) {
case "SET_VISIBILITY_FILTER":
return action.filter;
default:
return state;
}
}
const {combineReducers} = Redux;
const todoAppReducer = combineReducers({
todos: todosReducer,
visbilityFilter: visbilityFilterReducer,
});
// Helper Function
const getVisibleTodos = (todos, filter) => {
switch(filter) {
case "SHOW_ALL":
return todos;
case "SHOW_ACTIVE":
return todos.filter(t => !t.completed);
case "SHOW_COMPLETED":
return todos.filter(t => t.completed);
default:
return todos;
}
}
// Action Creators
let nextTodoId = 0;
const addTodo = (text) => {
return {
type: "ADD_TODO",
text,
id: ++nextTodoId;
}
}
const toggleTodo = (id) => {
return {
type: "TOGGLE_TODO",
id,
};
}
const setVisibilityFilter = (filter) => {
return {
type: "SET_VISIBILITY_FILTER",
filter: filter
};
}
// Components
const {Component} = React;
const {connect} = ReactRedux;
const Link = ({
active,
onClick,
children
}) => {
return active
? <span>{children}</span>
: <a href= "#"
onClick={e => {
e.preventDefault();
onClick();
}
}>
{children}
</a>
};
const mapStateToPropsFilterLink = (state, ownProps) => {
return {
active: ownProps.filter === state.visbilityFilter,
};
}
const mapDispatchToPropsFilterLink = (dispatch, ownProps) => {
return {
onClick: () => {
dispatch(setVisibilityFilter(ownProps.filter))
}
};
}
const FilterLink = connect(
mapStateToPropsFilterLink,
mapDispatchToPropsFilterLink,
)(Link);
const Footer = () => {
return (
<p>Show: &nbsp;&nbsp;
<FilterLink filter="SHOW_ALL">
All</FilterLink>&nbsp;&nbsp;
<FilterLink filter="SHOW_ACTIVE">
Active</FilterLink>&nbsp;&nbsp;
<FilterLink filter="SHOW_COMPLETED">
Completed</FilterLink>
</p>
);
}
const ToDo = ({id, text, completed, toggleTodo}) => {
const completedStyle = {
textDecoration: "line-through",
};
return (
<li onClick={toggleTodo.bind(null, id)}
style={completed ? completedStyle : null }>
{text}</li>
);
}
const ToDoList = ({todos, toggleTodo}) => {
return (
<ul>
{todos.map(todo =>
<ToDo
key={todo.id}
{...todo}
toggleTodo={toggleTodo} />
)}
</ul>
);
}
// This component is neither presentational nor container.
// This is kept along with behaviour because we can not break down further.
// SECOND param is context if we specify contextTypes.
let AddTodo = ({dispatch}) => {
let input;
return (
<div>
<input type="text" ref={node => {input = node;}} />
<button type="button"
onClick={() => {
dispatch(addTodo(input.value));
input.value = "";
}}>Submit</button>
</div>
);
}
// // SPECIFYING contextTypes IS A MUST to use context feature
// AddTodo.contextTypes = {
// store: React.PropTypes.object,
// };
AddTodo = connect(
// null, // There is no need to subscribe to this store, so we are passing mapStateToProps as null
// null, // If we pass null or falsy value to second param, connect will pass 'dispatch' by default as prop to the component
// So we can go without passing any thing to conenct function
// if we don't want component to subscribe t store changes
// as well as when component only needs to access dispatch function as props.
)(AddTodo);
const mapStateToProps = (state) => {
return {
todos: getVisibleTodos(state.todos, state.visbilityFilter),
};
}
const mapDispatchToProps = (dispatch) => {
return {
toggleTodo: id => {
dispatch(toggleTodo(id));
}
};
}
const VisibleTodoList = connect(
mapStateToProps,
mapDispatchToProps,
)(ToDoList);
const TodoApp = () => {
return (
<div>
<AddTodo />
<VisibleTodoList />
<Footer />
</div>
);
}
// class Provider extends Component {
// getChildContext () {
// return {
// store: this.props.store,
// };
// }
// render () {
// return this.props.children;
// }
// }
// // SPECIFYING childContextTypes IS A MUST to use context feature
// Provider.childContextTypes = {
// store: React.PropTypes.object,
// };
const {createStore} = Redux;
const {Provider} = ReactRedux;
ReactDOM.render(
<Provider store={createStore(todoAppReducer)}>
<TodoApp/>
</Provider>,
document.getElementById("app"));
</script></body>
</html>
// Reducers
const todoReducer = (state = {}, action) => {
switch(action.type) {
case "ADD_TODO":
return {...action.todo, completed: false};
case "TOGGLE_TODO":
if (state.id !== action.id) {
return state;
}
return {
...state,
completed: !state.completed
}
default:
return state;
}
}
const todosReducer = (state = [], action) => {
switch(action.type) {
case "ADD_TODO":
return [...state, todoReducer(undefined, action)];
case "TOGGLE_TODO":
return state.map(todo => todoReducer(todo, action));
default:
return state;
}
}
const visbilityFilterReducer = (state = "SHOW_ALL", action) => {
switch(action.type) {
case "SET_VISIBILITY_FILTER":
return action.filter;
default:
return state;
}
}
const {combineReducers} = Redux;
const todoAppReducer = combineReducers({
todos: todosReducer,
visbilityFilter: visbilityFilterReducer,
});
// Helper Function
const getVisibleTodos = (todos, filter) => {
switch(filter) {
case "SHOW_ALL":
return todos;
case "SHOW_ACTIVE":
return todos.filter(t => !t.completed);
case "SHOW_COMPLETED":
return todos.filter(t => t.completed);
default:
return todos;
}
}
// Action Creators
let nextTodoId = 0;
const addTodo = (text) => {
return {
type: "ADD_TODO",
text,
id: ++nextTodoId;
}
}
const toggleTodo = (id) => {
return {
type: "TOGGLE_TODO",
id,
};
}
const setVisibilityFilter = (filter) => {
return {
type: "SET_VISIBILITY_FILTER",
filter: filter
};
}
// Components
const {Component} = React;
const {connect} = ReactRedux;
const Link = ({
active,
onClick,
children
}) => {
return active
? <span>{children}</span>
: <a href= "#"
onClick={e => {
e.preventDefault();
onClick();
}
}>
{children}
</a>
};
const mapStateToPropsFilterLink = (state, ownProps) => {
return {
active: ownProps.filter === state.visbilityFilter,
};
}
const mapDispatchToPropsFilterLink = (dispatch, ownProps) => {
return {
onClick: () => {
dispatch(setVisibilityFilter(ownProps.filter))
}
};
}
const FilterLink = connect(
mapStateToPropsFilterLink,
mapDispatchToPropsFilterLink,
)(Link);
const Footer = () => {
return (
<p>Show: &nbsp;&nbsp;
<FilterLink filter="SHOW_ALL">
All</FilterLink>&nbsp;&nbsp;
<FilterLink filter="SHOW_ACTIVE">
Active</FilterLink>&nbsp;&nbsp;
<FilterLink filter="SHOW_COMPLETED">
Completed</FilterLink>
</p>
);
}
const ToDo = ({id, text, completed, toggleTodo}) => {
const completedStyle = {
textDecoration: "line-through",
};
return (
<li onClick={toggleTodo.bind(null, id)}
style={completed ? completedStyle : null }>
{text}</li>
);
}
const ToDoList = ({todos, toggleTodo}) => {
return (
<ul>
{todos.map(todo =>
<ToDo
key={todo.id}
{...todo}
toggleTodo={toggleTodo} />
)}
</ul>
);
}
// This component is neither presentational nor container.
// This is kept along with behaviour because we can not break down further.
// SECOND param is context if we specify contextTypes.
let AddTodo = ({dispatch}) => {
let input;
return (
<div>
<input type="text" ref={node => {input = node;}} />
<button type="button"
onClick={() => {
dispatch(addTodo(input.value));
input.value = "";
}}>Submit</button>
</div>
);
}
// // SPECIFYING contextTypes IS A MUST to use context feature
// AddTodo.contextTypes = {
// store: React.PropTypes.object,
// };
AddTodo = connect(
// null, // There is no need to subscribe to this store, so we are passing mapStateToProps as null
// null, // If we pass null or falsy value to second param, connect will pass 'dispatch' by default as prop to the component
// So we can go without passing any thing to conenct function
// if we don't want component to subscribe t store changes
// as well as when component only needs to access dispatch function as props.
)(AddTodo);
const mapStateToProps = (state) => {
return {
todos: getVisibleTodos(state.todos, state.visbilityFilter),
};
}
const mapDispatchToProps = (dispatch) => {
return {
toggleTodo: id => {
dispatch(toggleTodo(id));
}
};
}
const VisibleTodoList = connect(
mapStateToProps,
mapDispatchToProps,
)(ToDoList);
const TodoApp = () => {
return (
<div>
<AddTodo />
<VisibleTodoList />
<Footer />
</div>
);
}
// class Provider extends Component {
// getChildContext () {
// return {
// store: this.props.store,
// };
// }
// render () {
// return this.props.children;
// }
// }
// // SPECIFYING childContextTypes IS A MUST to use context feature
// Provider.childContextTypes = {
// store: React.PropTypes.object,
// };
const {createStore} = Redux;
const {Provider} = ReactRedux;
ReactDOM.render(
<Provider store={createStore(todoAppReducer)}>
<TodoApp/>
</Provider>,
document.getElementById("app"));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment