Skip to content

Instantly share code, notes, and snippets.

@balazimichal
Last active July 9, 2018 11:56
Show Gist options
  • Save balazimichal/ed54fbcefb3f70797720fcf240391877 to your computer and use it in GitHub Desktop.
Save balazimichal/ed54fbcefb3f70797720fcf240391877 to your computer and use it in GitHub Desktop.
React simple one page app with search and local storage.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>React Todo List</title>
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
todos: [],
value: '',
query: ''
}
this.removeTodo = this.removeTodo.bind(this)
this.voteUp = this.voteUp.bind(this)
this.formOnSubmit = this.formOnSubmit.bind(this)
this.formOnChange = this.formOnChange.bind(this)
this.searchTodos = this.searchTodos.bind(this)
}
componentDidMount() {
// mount the items from local db
var retrievedTodos = JSON.parse(localStorage.getItem('todos'))
if(retrievedTodos) {
this.setState({
todos: retrievedTodos
})
return
}
}
removeTodo(td) {
this.setState((previousState) => ({
todos: previousState.todos.filter((todo)=> {
if(td.id !== todo.id) {
return todo
}
})
}),
function() {
this.dbUpdate()
}
)
}
voteUp(td) {
this.setState((prevState) => ({
todos: prevState.todos.map((todo) => {
if(td.id === todo.id) {
todo.vote = todo.vote + 1
return todo
} else {
return todo
}
})
}),
function() {
this.dbUpdate()
})
}
formOnSubmit(e) {
e.preventDefault()
this.setState({
todos: [...this.state.todos, {id: this.randID(), title: this.state.value, vote: 0}],
value: ''
},
function() {
this.dbUpdate()
}
)
//localStorage.setItem('todos', JSON.stringify([...this.state.todos, {id: this.randID(), title: this.state.value, vote: 0}]));
}
formOnChange(value) {
this.setState({
value: value
})
}
randID() {
return Math.random().toString(36).replace(/[^a-z]+/g, '').substr(2, 10);
}
searchTodos(query) {
this.setState({
query: query
})
}
dbUpdate() {
console.log('db updated')
localStorage.setItem('todos', JSON.stringify(this.state.todos))
}
render() {
const showingTodos = this.state.query === ''
? this.state.todos
: this.state.todos.filter((td) => (
td.title.toLowerCase().includes(this.state.query.toLowerCase())
))
return (
<div>
<h1>Todo</h1>
Search: <input type='text' value={this.state.query} onChange={(event) =>(this.searchTodos(event.target.value))} />
<form onSubmit={this.formOnSubmit}><input onChange={(e) => (this.formOnChange(e.target.value))} type='text' value={this.state.value} /><button>Add TODO</button></form>
<ol>
{showingTodos.sort((a, b) => a.vote < b.vote).map((todo) => (
<li key={todo.id}>{todo.title} (votes: {todo.vote}) <button onClick={(e) => (this.voteUp(todo))}>+</button> <button onClick={(e) => (this.removeTodo(todo))}>Remove</button></li>
))}
</ol>
</div>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
</script>
<!--
Note: this page is a great way to try React but it's not suitable for production.
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
To set up a production-ready React build environment, follow these instructions:
* https://reactjs.org/docs/add-react-to-a-new-app.html
* https://reactjs.org/docs/add-react-to-an-existing-app.html
You can also use React without JSX, in which case you can remove Babel:
* https://reactjs.org/docs/react-without-jsx.html
* https://reactjs.org/docs/cdn-links.html
-->
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment