0

I have a simple list made in React with creation/delete/update function. I have a problem in the update, where when I modify the input, the input changes the value, but in the console.log I see the same array updating with no changes made.

Normally after the update the new list should be updated with the new changes, which is not the case. Instead in the new array, I have name: undefined Did I miss something ?

import React, { useEffect, useState } from "react";
import { v4 as uuidv4 } from "uuid";

export default () => {

  const initialList = [
    {
      id: "a",
      name: "John",
    },
    {
      id: "b",
      name: "Eric"
    },
    {
      id: "c",
      name: "Jonathan"
    },
  ];

  const [list, setList] = React.useState(initialList);
  const [name, setName] = React.useState("");

  function handleChangeUpdate(id) {
    const newList = list.map((item) => {
      if (item.id === id) {
        const updatedItem = {
            ...item,
          };
   
        return updatedItem;
      }
      return item;
    });
 
    setList(newList);
    console.log(newList);
  }
 
  return (
    <div>                
        <ul >             
            <div>
                {list.map((item) => (                                                                    
                    <li key={item.id}>                      
                    <input className="form-control" onChange={()=> handleChangeUpdate(item.id)} defaultValue={item.name}></input>
                    </li>
                    ))}                   
            </div>               
        </ul>
    </div>
  );
};

2 Answers 2

1

You never update the name of the item, just copy the existing item by returning

    const updatedItem = {
        ...item,
      };

    return updatedItem;

If you 1) pass the updated value to handleChangeUpdate and 2) use that value to change the name of the matching item, it works:

const F = () => {

  const initialList = [
    {
      id: "a",
      name: "John",
    },
    {
      id: "b",
      name: "Eric"
    },
    {
      id: "c",
      name: "Jonathan"
    },
  ];

  const [list, setList] = React.useState(initialList);
  const [name, setName] = React.useState("");

  function handleChangeUpdate(id, value) {
    const newList = list.map((item) => {
      if (item.id === id) {
        const updatedItem = {
            ...item,
            name: value
          };
   
        return updatedItem;
      }
      return item;
    });
 
    setList(newList);
    console.log(newList);
  }
 
  return (
    <div>                
        <ul >             
            <div>
                {list.map((item) => (                                                                    
                    <li key={item.id}>                      
                    <input className="form-control" onChange={(e)=> handleChangeUpdate(item.id, e.target.value)} defaultValue={item.name}></input>
                    </li>
                    ))}                   
            </div>               
        </ul>
    </div>
  );
};

ReactDOM.render(<F />, document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.0/umd/react-dom.production.min.js"></script>
<div id="app"></div>

Sign up to request clarification or add additional context in comments.

1 Comment

It works! I'm still a complete beginner regarding React/js so, my bad. Thank you very much. I needed to pass an actual value for the updatedItem which in my case was empty.
0

You are not changing anything in the updatedItem object. You are spreading the exact same fields from item into the new object, without modifying any key. So there'll be no changes

5 Comments

I tried to put item.id=id and item.name=name and didn't work
@AlyaKra do you wish to update the name state?
Yes. But it's alright I managed to solved it thanks to the post above.
As a controlled element you should swap out defaultValue for value aswell
@Steve Tomlin The problem with value is that it didn't want to change at at, like the input was bloqued, so by trying defaultValue it worked. I have no idea.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.