Search code examples
reactjs

React form is hitting onChange but existing value is not changing


I am trying to edit some existing data, for which I need to show the existing value in input field and then I need to update the fields value. but if I am trying to delete the value of input field, it is not giving any effect on the input field, but if I am printing the onChange event response, it is just hitting, but no change in the value . but I need the changed value. otherwise I can't update the state, as a result edit will not be performed. Help please.

The code is:

import React, { useEffect, useState } from 'react'
import { Form,Button } from 'react-bootstrap';

const EditData = () => {
   
    let [old,setOld]=useState({
        id:"ab123",bookname:"Book1",author:"John Doe",price:"1,234"
    })   
  
    let changeHandler=(event)=>{            
        let {value,name}=event.target;
        console.log(name,value);        
    }

    let submitHandler=(event)=>{
      event.preventDefault();
      console.log("submitted");
      
    }

  return (
    <div>
          <Form onSubmit={submitHandler}>
          <Form.Group className="mb-3" controlId="booksname">
            <Form.Label>Name</Form.Label>
            <Form.Control type="text"  name="bookname" value={old.bookname} onChange={changeHandler} />
          </Form.Group>

          <Form.Group className="mb-3" controlId="booksauthor">
            <Form.Label>Author</Form.Label>
            <Form.Control type="text" name="author" value={old.author} onChange={changeHandler}/>
          </Form.Group>

          <Form.Group className="mb-3" controlId="booksprice">
            <Form.Label>Price</Form.Label>
            <Form.Control type="text" name="price" value={old.price} onChange={changeHandler}/>
          </Form.Group>

          <Button variant="outline-dark" type="submit">
            Submit
          </Button>
        </Form>
    </div>
  )
}

export default EditData

If I am trying to modifying any field's value, 1st characters is changing, but others are not. For example: I have value John Doe as Author name, I am clicking at that, then trying to remove the lastname, then no change is happing in input field, just the changehandler showing in console :
3 author John Do (yes only e is removed, and 3 is representing the number of time that message is printed)

Sandbox: https://codesandbox.io/p/sandbox/admiring-bash-xmx3l3?workspaceId=aa2c26f8-c8a3-44c2-80be-9c87a842fad1


Solution

  • but I need the changed value. otherwise I can't update the state, as a result edit will not be performed. Help please.

    For a controlled input, the changed value is to be collected into the respective state character-wise. The below code does that.

      let changeHandler = (event) => {
        let { value, name } = event.target;
        console.log(name, value);
        const newObj = {
          ...old,
          [name]: value,
        };
        setOld(newObj);
      };
    

    Further info :

    Optimizing re-rendering on every keystroke

    Deferring re-rendering for a part of the UI

    Sample code - full listing

    Please see the test run results enclosed below and then please try the below code. See if it is possible to delete and update the field values. The code is very much the same of yours original code. The only change applied is in the changeHandler.

    The onChange event is triggered on character-wise, this is the most important point to be taken care in this case, the rest of the codes need to align accordingly.

    This character based input is applicable while deleting as well as editing.

    For example, deleting character-wise the string "book1" in the field name.

    1. "Book1" - by deleting the trailing character "1", the new value received in the onChange will be "book". This value needs to be updated into the state old instantly. This would sync the value in the input as well so that the state and the input will be the same value "Book".

    2. "Book" - delete "k" - will sync the state and value with "Boo".

    3. "Boo" - delete "o" - will sync the state and value with "Bo".

    4. "Bo" - delete "o" - will sync the state and value with "B".

    5. "B" - delete "B" - will sync the state and value with "".

    Now the state has become empty along with the visual display.

    Another example, if we delete the whole string "Book1" in one short by selecting it, the changed value in the event will be "", this will be set to the state immediately, so that the input value will also be set to "".

    Please comment for further assistance.

    App.js

    import React, { useEffect, useState } from 'react';
    import { Form, Button } from 'react-bootstrap';
    
    const EditData = () => {
      let [old, setOld] = useState({
        id: 'ab123',
        bookname: 'Book1',
        author: 'John Doe',
        price: '1,234',
      });
    
      let changeHandler = (event) => {
        let { value, name } = event.target;
        console.log(name, value);
        const newObj = {
          ...old,
          [name]: value,
        };
        setOld(newObj);
      };
    
      let submitHandler = (event) => {
        event.preventDefault();
        console.log('submitted');
      };
    
      return (
        <div>
          <Form onSubmit={submitHandler}>
            <Form.Group className="mb-3" controlId="booksname">
              <Form.Label>Name</Form.Label>
              <Form.Control
                type="text"
                name="bookname"
                value={old.bookname}
                onChange={changeHandler}
              />
            </Form.Group>
    
            <Form.Group className="mb-3" controlId="booksauthor">
              <Form.Label>Author</Form.Label>
              <Form.Control
                type="text"
                name="author"
                value={old.author}
                onChange={changeHandler}
              />
            </Form.Group>
    
            <Form.Group className="mb-3" controlId="booksprice">
              <Form.Label>Price</Form.Label>
              <Form.Control
                type="text"
                name="price"
                value={old.price}
                onChange={changeHandler}
              />
            </Form.Group>
    
            <Button variant="outline-dark" type="submit">
              Submit
            </Button>
          </Form>
        </div>
      );
    };
    
    export default EditData;
    

    Test results

    "Book1" edited to "Boo"

    "Book1" edited to "Boo"

    Author column value deleted wholly

    Author column value deleted wholly