Input field does not allow me to type - REACT JSX

Viewed 47

I am very new to react and have been making a simple "CRUD" inventory list. Everything seems to be working fine except for the 'inventoryItem' function. Whenever i remove the 'value' field with defaultValue. This allows me to type in text, however when i edit the text, if i do not type anything, when i save it - it is blank. When i remove this 'defaultValue' to value, the field only allows me to type one character. If i save another field without having typed anything, it saves as the previous field i edited.

Here is an image of what the website looks so far. here is my code:

    import React from 'react'
import {useState, useEffect} from 'react' 
import HandleState from './handleState';

export const InventoryItem = (props) => {
    
    
    const [isEditing,setIsEditing] = useState(false);
    function edit(event){
        props.onChange(event)
        setIsEditing(true); 
    };
    function edit2(event){
        props.onClick(event,props.ind)
        setIsEditing(false); 
        
    };
    function del(event){
        props.onDel(event,props.ind)
    };

    /*inventoryList array is distributed to the following div for editing and deletion purposes.*/
    /*If new field added to inventory items, simply add another div below the price div.  */
    return (
        <div className = "inventItem " style = {{display:'flex', flexDirection:'row'}}>
                
                <div className="item" style = {{display:'flex', paddingRight:20}}>
                        Item: {isEditing ?<input type ="text" name ="item" placeholder = "Item" defaultValue ={props.itemn.item}  onChange = {props.onChange}  /> :  props.itemn.item} 
                </div>
                <div className="price" style = {{display:'flex',paddingRight:20}}>
                    Price: {isEditing ? <input  type ="text" name ="price" placeholder = "Price" defaultValue ={props.itemn.price} onChange = {props.onChange} /> :  props.itemn.price } 
                    
              
                </div>
                {isEditing ? <button onClick={event =>edit2(event)}>  Save </button>  : <button onClick={event=>edit(event)}>  Edit </button> }
                {isEditing ? "can't delete while editing!": <button onClick={del}>  Delete </button> }
        </div>
        )
}


    import {useState, useEffect} from 'react' 

/* Any state change functions can be found here. Updating  & Deleting */
const HandleState = () => {

    /* CREATING INITIAL OBJECT, AND OBJECT ARRAY  */
    const [inventoryItems, setInventoryItems] = useState([]);

    const [readList, setReadList] = useState(false);
    

    
    /* Inventory fields can be added by simply updating iItems constants below, i.e. if wanted to add Quantity, can be placed right after price. */
    const [iItems,setiItems] = useState(
            {
                item: '',
                price: '' 
            }
    );
     /* Double constant definition to seperate adding input from editing input. */
    const [iItems2, setiItems2] = useState(
        {
            item : '',
            price : '' 
        }
    );

    /* FOR ADDING INVENTORY ITEMS  */ 
    const handleChange = e => {
        e.preventDefault() ;
        const target = e.target;
        const value = target.value;
        const name = target.name; 

        setiItems({
            ...iItems,
            [name]:value
        })
       
    }

    const handleSubmit = e => {
        e.preventDefault() ;
        const data = [
            ...inventoryItems,
            iItems
        ];

        setInventoryItems(data);
        setiItems({
            item: '',
            price: '' 
        });
    }
    
      /* FOR EDITING AND DELETING  */
    const handleChangeEdit = (event) => {

        event.preventDefault() ;
        const target = event.target;
        const value = target.value; 
        const name = target.name; 
        
       setiItems2({
            ...iItems2,
           [name]:value
        }); 
        console.log(value)
    }

    const handleUpdateOnClick  = (event, index) => {
        event.preventDefault() ;
        const data = [...inventoryItems.slice(0,index), iItems2,...inventoryItems.slice(index+1)]
        setInventoryItems(data);
        setiItems2({
            item: '',
            price: '' 
        });
      
    }

    const handleDelete  = (event, index) => {
        event.preventDefault() ;
        const data = [...inventoryItems.slice(0,index),...inventoryItems.slice(index+1)]
        setInventoryItems(data);
    }


    /* For reading the inventory list */

    function isReading (props) {
        setReadList(props)
    }
    return {inventoryItems, iItems,iItems2, handleChange, handleSubmit, handleChangeEdit, handleUpdateOnClick, handleDelete, readList,isReading}
}

export default HandleState

    import './App.css';
import {useState, useEffect} from 'react' 

import { AddInventoryItem } from './Components/AddInventoryItem'
import { InventoryItem } from './Components/inventoryItem'
import CSVReport from './Components/CSVReport';
import HandleState from './Components/handleState';

function App() {
  const {inventoryItems, iItems,iItems2, handleChange, handleSubmit, handleChangeEdit, handleUpdateOnClick, handleDelete,readList,isReading}=HandleState();

  return (
      <div>
        <h1> Simple Inventory Tracking List</h1> 
          {inventoryItems.map((items,index) => <InventoryItem key={index} ind={index} itemn={items} onChange= {handleChangeEdit}  onClick = {handleUpdateOnClick} onDel = {handleDelete} />)}
          
           {/*If fields added, i.e. quantity, simply add a quantity: {iTems.quantity} attribute to the parameters below.*/} 
          <AddInventoryItem item={iItems.item} price = {iItems.price} onSubmit={handleSubmit} onChange = {handleChange} /> 

          {readList ? <div> <button onClick = {() => isReading(false)}> Close </button> {inventoryItems.map((items,index) => <li key={index}> {items.item}, {items.price} </li>) } </div>: <button onClick = {()=>isReading(true)}> Read Inventory List </button> } 
          <CSVReport inventoryItems = {inventoryItems} />            
      </div>
  )
}

export default App;

UPDATE////!!

I have changed the handleChangeEdit to have the following lines of code

 const handleChangeEdit = (event,index) => {

        event.preventDefault() ;
        const target = event.target;
        const value = target.value; 
        const name = target.name; 
        
        setiItems2({
            ...iItems2,
           [name]:value
        }); 
        console.log(value)
        const data = [...inventoryItems.slice(0,index), iItems2,...inventoryItems.slice(index+1)] 
        setInventoryItems(data);
    }

It seems now changing the inventoryItems function to have value instead of defaultValue works. However since iItems2 changes with every keystroke, iItems2 does not update correctly. and therefore updates inventoryItems incorrectly as well. Would anyone know syntactically how to go about this.

1 Answers

This is simple, you need to replace defaultValue with value like this

<input
   type="text"
   name="item"
   placeholder="Item"
   value={props.itemn.item}
   onChange={props.onChange}
/>
Related