1

I has a list of object stored in the state. I want to store input data into the object in a format like this.

{
    "parameter" : [{
        "id":"parameter1",
        "value":"value1"
    }, {
        "id":"parameter2", 
        "value":"value2"
    }]
}

The thing is the number of input is not constant. If there are 10 inputs, my object length should be 10.

(1) type "value1" in a input id=parameter1

{
    "parameter" : [{
        "id":"parameter1",
        "value":"value1"
    }]
}

(2) type "value2" in a input id=parameter2

{
    "parameter" : [{
        "id":"parameter1",
        "value":"value1"
    }, {
        "id":"parameter2", 
        "value":"value2"
    }]
}

(3) type "value3" in a input id=parameter1

{
    "parameter" : [{
        "id":"parameter1",
        "value":"value3"
    }, {
        "id":"parameter2", 
        "value":"value2"
    }]
}

I wrote onchange handler function but the length of the object always equal to 1. It changed id and value of my object only.

onChangeHandlerParameter = e => {
  this.setState({ parameter:[{"id": e.target.id,"value": e.target.value}]})
}

(1) type "value1" in a input id=parameter1

{
    "parameter" : [{
        "id":"parameter1",
        "value":"value1"
    }]
}

(2) type "value2" in a input id=parameter2

{
    "parameter" : [{
        "id":"parameter2",
        "value":"value2"
    }]
}
1
  • You have to modify the array stored in parameter. At the moment you're overwriting the existing array with a new one. Commented Jul 21, 2018 at 9:36

3 Answers 3

3

The problem is with on change handler

onChangeHandlerParameter = e => {
  this.setState((prevState) => {
          parameter:[
                    ...prevState.parameter,
                    {"id": e.target.id,"value": e.target.value}
                    ]
               });
}

You are changing your state but overwriting the existing one. so you are getting only one item in the array every time that also the latest you added.

'...' is spreader operator and it is spreading of array in your case.

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

4 Comments

Thanks for your help. However, code you wrote above doesn't work. System warned me that parameter is unused label. I edited the code but it still doesn't work. It showed "Cannot read property 'setState' of undefined" [Code] onChangeHandlerParameter(e){ this.setState({ parameter:[...this.prevState.parameter,{"id": e.target.id,"value": e.target.value}]})}
and that error Cannot read property 'setState' of undefined" is totally because your function is not bind with 'this' in the constructor
define your state with parameter then warning might go
"Cannot read property 'setState' of undefined" error is fixed. But when I type 'asd' in input box id='url', it always produce two elements in a array. i.sstatic.net/AqLqg.jpg
0

You should add the item (push) to the parameter array, the current code is just put new values to the whole array.

Could be changed to something like this:

onChangeHandlerParameter = e => {
   const { parameter } = this.state;
   parameter.push({"id": e.target.id,"value": e.target.value})
   this.setState({ parameter })
}

3 Comments

this wrong way of doing. you are mutating the state
de-structured element is referenced element. so when you are manipulating parameter it will directly affect the state.
State should never be edited directly, always use an immutable way, make use of spread operstor {...this.state}
0

When you write this way

onChangeHandlerParameter = e => {
  this.setState({ parameter:[{"id": e.target.id,"value": e.target.value}]})
}

you are actually overwriting the existing state, this will not work, it will always have your last input entered data.

To make this work you need to tweak this a little bit using spread operator.

Fix:

    onChangeHandlerParameter = e => {
    const currentState = {...this.state};
    const edittedParametersList = [...currentState.parameter];
    let element = {};
    element.id = e.target.id;
    element.value = e.target.value;
    edittedParametersList.parameter.push(element);
    this.setState(edittedParametersList);
  }

This way your code will work and also we are making sure we don't mutate state directly ( Which is a best practice ), we are editing it in an immutable fashion.

happy hacking!

1 Comment

Thanks for your help. However, the system showed error (TypeError: Cannot read property 'push' of undefined). I defined this.state={parameter=[]} in the constructor. I'm not sure is it relate to this error.

Your Answer

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