0

Summary

I am trying to create todo list in ReactJS. I expect only one list item to be added per action.

Actual Behavior

When I am adding to my todolist item, it adds the item twice.

App.js


import Header from "./components/Header";
import List from "./components/List";
import {useState} from "react";

function App() {

    const [items, setItem] = useState(function () {
            const storageItemsString = localStorage.getItem('items');
            if (storageItemsString) {
                return JSON.parse(storageItemsString);
            } else {
                return [];
            }
        }
    );

    function addItem(fieldValue) {
          setItem( (prevItems) => {
              const newItems = prevItems.concat(fieldValue);
              localStorage.setItem('items', JSON.stringify(newItems));
              return newItems;
          });
    }


    return (
        <div className="App">
            <div className="wrapper">
                <Header/>
                <List addItem={addItem} items={items}/>
            </div>
        </div>
    );
}

export default App;



List jsx


import React, {useEffect} from 'react';
import {Button, TextField} from "@mui/material";
import ListItem from "./listItem";

function List(props) {

    useEffect(() => {
        const textField = document.querySelector('#list-field');
        const button = document.querySelector('.button');

        button.addEventListener('click', function(e) {
            if (textField.value !== '') {
                props.addItem(textField.value);
            }
        });
    }, [props]);

    return (
        <div className="list-section">
            <form action="#" className="list-form">
                <TextField variant="outlined" label="Enter something" id="list-field" multiline
                           rows={4}/>
                <Button variant="contained" className="button">Add item</Button>
            </form>
            <div className="list-items">
                {props.items.map( (item) => <ListItem text={item} />)}
            </div>
        </div>
    );
}

export default List;

ListItem jsx


import React from 'react';
import DeleteIcon from '@mui/icons-material/Delete';

function ListItem(props) {
    return (
        <div className="list-item">
            <div className="item-content">{props.text}</div>
            <span className="delete-icon">
                <DeleteIcon />
            </span>
        </div>
    );
}

export default ListItem;

JGallardo
  • 11,074
  • 10
  • 82
  • 96
Roman
  • 33
  • 7
  • 1
    You shouldn't use JS methods to add event listeners in React. `
    ` and make a `someFunction` to do whatever you want
    – Guy Incognito Feb 14 '23 at 13:59
  • Got it, but how can I take my text field value then? Because my function must receive a value to do something. – Roman Feb 14 '23 at 14:04
  • 2
    https://reactjs.org/docs/forms.html#controlled-components <-- I suggest you go through the entire page there to learn the proper way to manage forms in React. https://beta.reactjs.org/reference/react-dom/components/input for how to use with Hooks. Specifically: https://beta.reactjs.org/reference/react-dom/components/input#reading-the-input-values-when-submitting-a-form – Guy Incognito Feb 14 '23 at 14:05
  • I've fixed everything. Thanks – Roman Feb 15 '23 at 07:44

0 Answers0