1

I am rendering in my React application an Array and for each Array I have an input element. This elements gets as name the ID from the Array entryand a value can be entered.

I have a handleChange() functions, which gets the ID and the input value.

This data should be added to an Array, which I want to save to my State.

Later on, I have for each Array entry a Submit button, where I have to send the input value to an API endpoint.

constructor(props: Props) {
    super(props);
    this.state = {
        sendTransferObj: []
    };
    this.handleChange = this.handleChange.bind(this);
}

...

handleChange(transId: string, event: React.ChangeEvent<HTMLInputElement>) {
    console.log(transId, event.target.value); // returns => '123', '1'

    let inputObject = [{ id: transId, value: event.target.value }]
    let arrayForState = [];

    const index = inputObject.findIndex(inputObject => inputObject.id != transId)

    if (index === -1) {
        arrayForState.push(inputObject);
    } else {
        console.log("object already exists")
    }

    console.log(arrayForState)

    this.setState({
        ...this.state,
        sendTransferObj: arrayForState
    }); // error!
}

...

<Form.Control as="input" name={trans.id} onChange={this.handleChange.bind(this, trans.id)} />

My problem is currently in my handleChange(), where the input value gets saved to my arrayForObject for one input, but if I enter in a second input element a value, it gets overwritten.

Also I get various errors, when I later want to do a setState() for save this Array.

This is my whole component which I am using for reference (getting the Array that I render from my state with Redux): https://codesandbox.io/s/practical-ptolemy-69zbu?fontsize=14&theme=dark

1 Answer 1

2

You need to append the inputObject to the sendTransferObj array in the current state instead of appending it to a new empty array (which will cause the overwriting). You can do this using the spread syntax

handleChange(transId: string, event: React.ChangeEvent<HTMLInputElement>) {
    let inputObject = [{ id: transId, value: event.target.value }]
    const index = inputObject.findIndex(inputObject => inputObject.id != transId)

    this.setState({
        ...this.state,
        sendTransferObj: index === -1 ? [
          ...this.state.sendTransferObj,
          inputObject
        ] : this.state.sendTransferObj
    });
}

This won't update the field when the inputObject is found, though. I would recommend storing the values in an object with the ID as keys instead (and formatting it into the desired format when requesting the API). This way, you don't have to iterate through the array to find the matching object.


constructor(props: Props) {
    super(props);
    this.state = {
        sendTransferObj: {}
    };
    this.handleChange = this.handleChange.bind(this);
}

...

handleChange(transId: string, event: React.ChangeEvent<HTMLInputElement>) {
      this.setState({
          ...this.state,
          sendTransferObj: {
            ...sendTransferObj,
            [transId]: event.target.value
          }
      }); 
  }
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for your time to answer my question! @hbentlov It works but the only problem left is, that for each input it adds a new object to the value: abload.de/img/screenshot2019-12-20a9fkkz.png
So if I enter 12for example, it should be [{id: '123', value: 12}]and not two objects with [{id: '123', value: 1}, {id: '123', value: 12}] :)
I updated the answer suggesting using an object instead of an array to store the values.

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.