2

I want to change the value in the input box in my react js application. I tried using this solution that uses spread.. but the value still won't change. what am I doing wrong? any help is appreciated..

here's my code:

import { useState, useEffect } from "react";

export default function App() {
  const [stuffs, setStuffs] = useState([]);

  useEffect(() => {
    getStuffs();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const getStuffs = () => {
    let data = [
      {
        id: 1,
        name: "candy",
        qty: 20
      },
      {
        id: 2,
        name: "book",
        qty: 15
      }
    ];
    setStuffs(data);
  };

  const handleChange = (e) => {
    console.log("stuffs1", stuffs);
    setStuffs(
      stuffs.map((item) =>
        item.id === e.target.id ? { ...item, qty: e.target.qty } : item
      )
    );
    console.log("stuffs2", stuffs);
  };

  return (
    <div className="App">
      {stuffs.length > 0 ? (
        stuffs.map((item, index) => (
          <div key={item.id}>
            <label>{item.name}</label>
            <input
              type="text"
              id={item.id}
              name="qty"
              value={item.qty}
              onChange={handleChange}
            />
          </div>
        ))
      ) : (
        <span>No data</span>
      )}
    </div>
  );
}

and here's the code sandbox

3 Answers 3

1

Since event.target.id defaults to a string, you'll need to convert it to number. You can add a + in the beginning to easily do that

Your code should look like

stuffs.map((item) =>
      item.id === +e.target.id ? { ...item, qty: e.target.qty } : item
    )

Another issue in your code is that you're using e.target.qty which is undefined. It should be +e.target.value instead. (Added + for the same reasons to convert it to a number)

Final code should look like

stuffs.map((item) =>
      item.id === +e.target.id ? { ...item, qty: +e.target.value } : item
    )
Sign up to request clarification or add additional context in comments.

1 Comment

just a little note for a fellow newbie like me: if there's more than 1 process that needs to be run when item.id matches the e.target.id, we can use curly brackets in the map callback function, we just have to return something (in this case, the item variable). so it'll look like this: stuffs.map((item) => { console.log('blah'); if (item.id === +e.target.id) { item = {...item, qty: +e.target.value}; return item;} });
1

e.target.id is a string, while item.id is a number, so try:

setStuffs(
      stuffs.map((item) =>
        item.id === Number(e.target.id) ? { ...item, qty: e.target.qty } : item
      )
    );

Comments

1

event.target.id evaluates to a string and item.id is a number. Thus, item.id === event.target.id would always evaluate to false.

use parseInt() instead

item.id === parseInt(e.target.id, 10)

Comments

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.