123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- import React, { Component } from 'react';
- import './App.css';
- import { connect, Provider } from 'react-redux';
- import { createStore, combineReducers } from 'redux';
- function todoReducer(state, action){
- if (typeof state === 'undefined'){
- return {items: JSON.parse(localStorage.todo || "[]")};
- }
- if (action.type === 'NEW_TODO'){
- console.log(state);
- return {items: [...state.items, {title: action.title, text: action.text, timestamp: (new Date()).getTime()}]}
- }
- if (action.type === 'DELETE_TODO'){
- let items = [];
- for (let i=0;i<state.items.length;i++){
- if (state.items[i].timestamp !== action.timestamp){
- items.push(state.items[i]);
- }
- }
- return {items};
- }
- }
- const reducers = combineReducers({
- todo: todoReducer,
- })
- var store = createStore(reducers)
- store.subscribe(() => {
- let state = store.getState();
- localStorage.todo = JSON.stringify(state.todo.items);
- })
- class ToDoItem extends Component {
- constructor(props){
- super(props);
- this.delete = this.delete.bind(this);
- }
- delete() {
- store.dispatch({type: "DELETE_TODO", timestamp: this.props.item.timestamp})
- }
- render() {
- return (
- <div>
- <h3> { this.props.item.title } </h3>
- <p> { this.props.item.text }</p>
- <span> { (new Date(this.props.item.timestamp)).toLocaleString() } {this.props.item.timestamp} </span>
- <button onClick={this.delete} >x</button>
- </div>
- );
- }
- }
- class ToDoForm extends Component {
- constructor (props) {
- super(props);
- this.save = this.save.bind(this);
- this.state = {valid: true};
- }
- validator(){
- return this.title.value && this.text.value;
- }
- save() {
- let valid = this.validator();
- this.setState({valid})
- if (valid){
- store.dispatch({type: 'NEW_TODO',
- title: this.title.value,
- text: this.text.value})
- this.title.value = '';
- this.text.value = '';
- }
- }
-
- render (){
- let style = {
- backgroundColor: this.state.valid ? '' : 'red'
- }
- return (
- <div>
- <input style={style} placeholder='title' ref={ c => this.title = c}/>
- <input style={style} placeholder='text' ref={ c => this.text = c} />
- <button onClick = { this.save } >Save</button>
- </div>
- );
- }
- }
- class ToDoList extends Component {
- render (){
- return (
- <div> <h1>TODO LIST</h1>
- <ToDoForm />
- { this.props.items.map( (item, index) => <ToDoItem key={index} item={item} />) }
- </div>
- );
- }
- }
- const mapStateToProps = function(store){
- return {
- items: store.todo.items
- };
- }
- ToDoList = connect(mapStateToProps)(ToDoList);
- class App extends Component {
- render() {
- return (
- <div className="App">
- <Provider store={store} >
- <ToDoList />
- </Provider>
- </div>
- );
- }
- }
- export default App;
|