0

I have a form in React which dynamically adds new input elements. This seems to be working ok but I cant seem to access the input values as shown in this screenshot...

console.log array

I have tried the following

console.log(this.state.telephone.name)

and...

console.log(this.state.telephone.tidx.name)

where tidx is the unique key.

Here is the constructor...

 constructor() {
        super();
        this.state = {
            role: "Installer",
            name: "",
            telephoneType: [{ name: "" }],
            telephone: [{ name: "" }],
            tidx: "",
            emailType: [{ email: "" }],
            email: [{ email: "" }],
            eidx: "",
            notes: ""
        };
    }

and this is my function to handle the input forms...

handleTelephoneChange = tidx => evt => {

        const newTelephone = this.state.telephone.map((telephone, tsidx) => {

            if (tidx !== tsidx) return telephone;
            return { ...telephone, name: evt.target.value };
        });
        this.setState({ telephone: newTelephone }, () => {
            // get state on callback
            console.log(this.state)
            console.log(this.state.telephone.name)
            console.log(this.state.telephone.tidx.name)
        }
        );
    };

and rendered like this...

{this.state.telephone.map((telephone, tidx) => (
<MDBRow key={tidx} className="grey-text flex-nowrap align-items-center no-gutters my-2">
<MDBCol md="12">
<input value={telephone.name} onChange={this.handleTelephoneChange(tidx)}placeholder={`Telephone No. #${tidx + 1}`} className="form-control"/>
</MDBCol>
    </MDBRow>
     ))}

Any advice greatly appreciated as I am fairly new to forms in React. Thanks.

1 Answer 1

2

telephone is an array, so you should be using index notation.

  console.log(this.state.telephone[tidx].name)

To render a corresponding phone-type for each telephone:

{this.state.telephone.map((telephone, tidx) => (
     <MDBRow key={tidx} className="grey-text flex-nowrap align-items-center no-gutters my-2">
        <MDBCol md="12">
            <input value={this.state.telephoneType[tidx].yourValue} onChange={this.defineYourTelephoneTypeEventHandler(tidx)}/>
            <input value={telephone.name} onChange={this.handleTelephoneChange(tidx)}placeholder={`Telephone No. #${tidx + 1}`} className="form-control"/>
        </MDBCol>
      </MDBRow>
 ))}
Sign up to request clarification or add additional context in comments.

10 Comments

Thats great thanks the index notation worked. I cant type anything in the input field if I use your event-handler suggestion..
@StevenCollins nice glad that first part worked for you. That's interesting, and you're not experiencing any issues with the UI with your initial code?
thats correct, it all worked ok previously. here is a quick video with my original event-handler screencast.com/t/pQOPVLff
I hope you dont mind another quick question related to my post which has been bugging me. I have another imput field called TelephoneType. Is it possible to do something like this or would they need to be seperate? {this.state.telephone.map((telephone, tidx, telephoneType, ttidx) => ()}
@StevenCollins you can not do that within your existing this.state.telephone.map(), that function strictly follows this argument structure. array.map((item, index, ownArray)) so you would not be able to a directly target your other array like that. However, if we assume that the order of the items in telephone arr correspond to the same order of items in telephoneType, you could just use the index of provided the first array to reach into the value of 2nd array. Similarly you would use index notation :)... Otherwise, you can just use a second .map() as well
|

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.