1

I have a table(array of objects) in React. I have a input box/ button for each row. Currently, I m using index in react local state (for input box/button). But 'index' results in messed up table, when filtered. Read link https://www.menubar.io/react-keys-index/ and trying to use 'keys'. Can someone help for accessing the array of input boxes and buttons using keys? My code is below:

 companies.map((company,index)=>{
 return (
 <tr key={company.id}>
   <td onClick={this.props.onClick.bind(this, company)}></td>       
   <td>{company.vacancy}</td>     
   <td key={company.id}>            
         <p><input type="text" value={this.state.company.messages[index] || ''} name={this.state.company.messages[index]} onChange={this.handleMessageChange.bind(this,company,index)}/></p>
         <p><button type="button" onClick={() => this.sendSMS(company,index)}>SMS</button></p>
  </td>                          
 </tr>
   );
  })

I have companyId as unique value.

6
  • Use company.id instead. For more info about the behavior you are getting, read the linked post below. Commented Jan 15, 2018 at 8:38
  • 2
    Possible duplicate of Understanding unique keys for array children in React.js Commented Jan 15, 2018 at 8:38
  • @Chris Yes but I m not sure how to access/ use 'keys' in an array of input boxes? Any link or example ? Commented Jan 15, 2018 at 8:39
  • What do you mean? Commented Jan 15, 2018 at 8:40
  • reactjs.org/docs/… Commented Jan 15, 2018 at 8:42

2 Answers 2

2

Since companyId is unique,it can be used as key.

In your example key should be used in tr and not in the inner td

<tr key={company.id}> - correct usage
<td key={company.id}> - Incorrect usage

Keys only make sense in the context of the surrounding array.

You can refer the Extracting Components with Keys in https://reactjs.org/docs/lists-and-keys.html which Incorrect and correct Key Usage

You can refer Understanding unique keys for array children in React.js for any operations in the array (filter in your case).

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

1 Comment

This is correct, but doesn't answer OP's issue. Take a look in the comments.
1

You shouldn't use arrays to store the values of items that can rearrange because then you would also have to rearrange the array in order to maintain the correct item-to-value relation.

Use an object instead:

<input 
  type="text"
  value={this.state.company.messages[company.id] || ''}
  name={this.state.company.messages[company.id]}
  onChange={this.handleMessageChange.bind(this, company)}
/>

Your state in the constructor would then look something like:

this.state = {
  company: {
    messages: {}
  }
};

This way, your messages per company are stored as:

company: {
 messages: {
   someCompanyId: "blah blah",
   anotherCompanyId: "blah",
   ...
 }
}

This makes the storing of the values independent of index and order.

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.