Skip to content

Instantly share code, notes, and snippets.

@saitoxu
Last active April 2, 2017 09:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save saitoxu/ea1f9838f288975bbbfe3722fe13d8ad to your computer and use it in GitHub Desktop.
Save saitoxu/ea1f9838f288975bbbfe3722fe13d8ad to your computer and use it in GitHub Desktop.
2017-04-02
import React, { Component } from 'react'
import { Link, Route, Switch } from 'react-router-dom'
import Form from './Form'
import Todo from './Todo'
import TodoList from './TodoList'
const Top = () => (
<div>Top</div>
)
const NoMatch = ({ location }) => (
<div>
<h3>No match for <code>{location.pathname}</code></h3>
</div>
)
export default class App extends Component {
constructor() {
super()
this.state = {
todos: []
}
}
handleSubmit(e) {
e.preventDefault()
const title = e.target.elements[0].value
if (!title) {
return
}
const desc = e.target.elements[1].value
const todos = this.state.todos.slice()
todos.push({
title: title,
desc: desc,
done: false
})
this.setState({ todos: todos })
e.target.elements[0].value = null
e.target.elements[1].value = null
}
toggleStatus(e) {
e.preventDefault()
const id = parseInt(e.currentTarget.getAttribute('data-id'), 10)
const todo = this.state.todos[id]
const todos = this.state.todos.slice()
todos[id] = {
title: todo.title,
desc: todo.desc,
done: !todo.done
}
this.setState({ todos: todos })
}
render() {
return (
<div>
<Link to="/">Top</Link>
<Form onSubmit={this.handleSubmit.bind(this)} />
<TodoList todos={this.state.todos} onClick={this.toggleStatus.bind(this)} />
<Switch>
<Route exact path="/" component={Top} />
<Route exact path="/:id" render={(props) => {
const todos = this.state.todos
return (
<Todo
todos={todos}
{...props}
/>
)
}} />
<Route component={NoMatch} />
</Switch>
</div>
)
}
}
import React, { Component } from 'react'
export default class Form extends Component {
render() {
return (
<div>
<form onSubmit={this.props.onSubmit}>
<input type="text" placeholder="title"/><br/>
<textarea placeholder="description" rows="8"></textarea><br/>
<button type="submit">Create</button>
</form>
</div>
)
}
}
import React, { Component } from 'react'
import { Redirect } from 'react-router-dom'
export default class Todo extends Component {
render() {
const id = parseInt(this.props.match.params.id, 10)
const todo = this.props.todos[id]
return (
todo ?
<div>
<h3>{todo.title}</h3>
<p>{todo.desc}</p>
</div> :
<Redirect to="/" />
)
}
}
import React, { Component } from 'react'
import { Link } from 'react-router-dom'
export default class TodoList extends Component {
render() {
return (
<div>
<ol>
{this.props.todos.map((todo, i) => {
const link = todo.done? 'Undone' : 'Done'
const className = todo.done? 'done' : null
return (
<li key={i}>
<Link to={`/${i}`} className={className}>{todo.title}</Link>
<a href="#" onClick={this.props.onClick} data-id={i} className='link'>{link}</a>
</li>
)
}, this)}
</ol>
</div>
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment