2
\$\begingroup\$

We have a todo list, which by default holds two of them. The newTodo means what has been recorded in the input form to be the next todo to be added. needsUpdate and idOfTodoToUpdate are used to handle the submission as an update to an existing todo.

First to handleSubmit we check if it is an updating operation or a create one.

In addition we have the delete operation directly from the onClick event.

My concerns is that update and create todos logic is mixed. I think there should be an easier way to accomplish the update and creaate operations, without needing to store in the App's state both needsUpdate and idOfTodoToUpdate.

import React, {Component} from 'react';
import logo from './logo.svg';
import './App.css';

class App extends Component {
    constructor(props) {
        super(props);

        this.state = {
            todos: [
                {
                    id: 1,
                    name: 'Play golf'
                },
                {
                    id: 2,
                    name: 'Clean Clothes'
                }
            ],
            newTodo: '',
            needsUpdate: false,
            idOfTodoToUpdate: null
        };
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
        this.deleteTodo = this.deleteTodo.bind(this);
        this.handleUpdateTodoClick = this.handleUpdateTodoClick.bind(this);
    }

    handleChange(event) {
        this.setState({newTodo: event.target.value});
    }

    handleSubmit(event) {
        event.preventDefault();

        if (this.state.needsUpdate) {

            this.updateTodo();

        } else {
            this.createTodo();
        }
    }

    createTodo() {
        this.setState((prevState) => ({
            todos: [
                ...prevState.todos,
                {
                    id:
                    prevState.todos.length + 1,
                    name:
                    this.state.newTodo
                }
            ],
            newTodo: ''
        }));
    }

    updateTodo() {
        let todos = this.state.todos;
        let newTodo = {id: this.state.idOfTodoToUpdate, name: this.state.newTodo};
        todos.splice(this.state.idOfTodoToUpdate - 1, 1, newTodo);

        this.setState({
            todos: todos,
            needsUpdate: false,
            idOfTodoToUpdate: null,
            newTodo: ''
        });
    }

    deleteTodo(id) {
        this.setState((prevState) => ({
            todos: prevState.todos.filter((todo) => todo.id !== id)
        }));
    }

    handleUpdateTodoClick(id) {
        const todoToUpdate = this.state.todos.filter((todo) => todo.id === id)[0];
        this.setState({
            newTodo: todoToUpdate.name,
            needsUpdate: true,
            idOfTodoToUpdate: id
        });
    }


    render() {
        // console.log(this.state.newTodo);
        return (
            <div className="App">
                <header className="App-header">
                    <img src={logo} className="App-logo" alt="logo"/>
                    <h1 className="App-title">CRUD REACT</h1>
                </header>
                <form onSubmit={this.handleSubmit}>
                    <input
                        type="text"
                        className="form-control my-3"
                        name='addTodo'
                        onChange={this.handleChange}
                        value={this.state.newTodo}
                        placeholder='Write your new todo here!'
                    />
                    <button
                        type="submit"
                        className='form-control btn-info mb-3'
                    >Create new todos
                    </button>
                </form>
                <div className="container">
                    <ul className="list-group">
                        {this.state.todos.map((todo) => {
                            return (
                                <li
                                    key={todo.id}
                                    className='list-group-item'
                                >
                                    {todo.id} {todo.name}
                                    <button
                                        className='btn-sm btn-danger ml-3'
                                        onClick={() => this.deleteTodo(todo.id)}
                                    >
                                        Delete
                                    </button>
                                    <button
                                        className='btn-sm btn-primary ml-3'
                                        onClick={() => this.handleUpdateTodoClick(todo.id)}
                                    >
                                        Update
                                    </button>
                                </li>
                            );
                        })}
                    </ul>
                </div>
            </div>
        );
    }
}

export default App;
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.