0

I try to set a number in an input field and keep it in a state. However when I try to set the state of the array, it doesn't get populated and when I try it with an anonymous function it creates something like

{
    "btm": {
        "btm": {
            "btm": {...}, 
            "top": 100}, 
        "top": 100}, 
    "top": 100
}

Here the code that does this:

const Numbers = (props) => {
    const [numbers, setNumbers] = useState({"btm": "1", "top": "100"});
    
    const fromNumber = (n) => {
        console.log(numbers);
        setNumbers((n) => {
            const copy = numbers;
            copy["btm"] = n;
            return copy;
        });
    }

return (
            <>
                <input variant="toolbar-input" defaultValue={numbers["btm"]} onChange={e => fromNumber(e.target.value)} />
            </>
);
}
user6329530
  • 596
  • 1
  • 7
  • 21

3 Answers3

3

As you are using useState, you can do:

const Numbers = (props) => {
  const [numbers, setNumbers] = useState({ btm: "1", top: "100" });

  const fromNumber = (n) => {
    console.log(numbers);
    setNumbers({...numbers, btm: n});
  };

  return (
    <>
      <input
        variant="toolbar-input"
        defaultValue={numbers["btm"]}
        onChange={(e) => fromNumber(e.target.value)}
      />
    </>
  );
};

Note that a map has unique keys, so you can go on with ES6 Spread Syntax.

2

You are overriding the variable n here.

const fromNumber = (n) => {
  console.log(numbers);
  setNumbers((n) => {
    const copy = numbers;
    copy["btm"] = n;
    return copy;
  });
}

Here n is a value received from the input:

const fromNumber = (n) => {

Here n is the previous state of variable numbers:

setNumbers((n) => {

So you are nesting older state in the new one.

Deykun
  • 1,298
  • 9
  • 13
  • For more information: see this question on [shadowing in JavaScript](https://stackoverflow.com/questions/11901427/an-example-of-variable-shadowing-in-javascript) – Brian Thompson Jul 02 '20 at 20:01
1

You are using the same variable name here - const fromNumber = (n) => {... and here setNumbers((n) => {....

Also you can go with ES6 Spread Syntax and convert state update function to this:

setNumbers((prevNumbers) => ({
   ...prevNumbers,
   btm: n,
}));
Yaroslav
  • 110
  • 4