Home > Software design >  Trying to render a list dynamically, but every time I submit the form a blank list item shows up
Trying to render a list dynamically, but every time I submit the form a blank list item shows up

Time:08-03

I'm messing around with React, just making a simple todo app. So far I have three components, the Todo item, the CreateTodo form, and a wrapper card. However, every time I type something in the input and try to submit it, a blank Todo item is rendered instead of one containing the typed message. Take a look: enter image description here

enter image description here

The message should appear next to the "Mark as Complete" and "Delete" buttons, but it just appears blank.

I suspect that the problem is in the addUser() or newTodoHandler() methods

App.js

import Card from './Components/Card';
import './App.css';
import 'bootstrap/dist/css/bootstrap.min.css';
import CreateTodo from './Components/CreateTodo';
import Todo from './Components/Todo';
import React, { useState } from 'react';

function App() {
  const [messages, setMessages] = useState([])

  const addUser = (message) => {
    setMessages((prevSetMessages) => { return [...prevSetMessages, { userTodo: message, id: Math.random().toString() }] }
    )
  }

  return (
    <Card>
      <Todo messages={messages} />
      <CreateTodo addUser={addUser} messages={messages} />
    </Card>
  );
}

export default App;

Todo.js

import React from 'react'

function Todo(props) {
    return (
        <ul>
            {props.messages.map((msg) =>
                <li key={msg.id}>
                    <div>
                        <h4>{msg.userTodo}</h4>
                        <div>
                            <button className="btn btn-success" type="submit">Mark As Complete</button>
                            <button className="btn btn-danger" type="submit">Delete</button>
                        </div>
                    </div>
                </li>
            )}
        </ul>

    )
}

export default Todo

CreateTodo.js

import React, { useState } from 'react'
import 'bootstrap/dist/css/bootstrap.min.css';

function CreateTodo(props) {
    const [show, setShow] = useState(true)
    const [buttonState, setButtonState] = useState('Add')

    const handleShow = () => {
        setShow(!show)

        if (show === true) {
            setButtonState('Close')
        } else {
            setButtonState('Add')
        }
    }

    const newTodoHandler = (event) => {
        event.preventDefault()
        props.addUser(event.target.value)
    }

    return (
        <div>
            <button className='btn btn-success' onClick={handleShow}>{buttonState}</button>

            {show ? null : <form className="input-group mb-3" onSubmit={newTodoHandler} >
                <input type="text" className="form-control" placeholder="Type Your Todo" />
                <div className="input-group-append">
                    <button className="btn btn-outline-secondary" type="submit">Add Todo</button>
                </div>
            </form>}
        </div>
    )
}

export default CreateTodo

Card.js

import React from 'react'
import classes from './Card.css'

function Card(props) {
    return (
        <div className="card border-secondary mb-3" >
            <div className="card-header">Todo List</div>
            <div className="card-body text-secondary">
                {props.children}
            </div>
        </div>
    )
}

export default Card

CodePudding user response:

in CreateTodo.js, newTodoHandler function

replace props.addUser(event.target.value) to props.addUser(event.target[0].value) , as you are taking values from form

  • Related