Todd Meder
Todd Meder

Reputation: 13

React-Native TextInput that edits dynamic object key:values

I'm working on a React-Native using Redux. One of the components renders a series of TextInput based on the elements in an object passed to it in it's props, that is read in from an API earlier in the app.

I want to be able to edit the value and have it updated in the state. The object's keys, values, and length are all dynamic. All of my redux actions and reducers work, and my component is properly receiving it's props, so I'll try to boil this down to a very simple example. To illustrate my problem, let's say the component receives this object in it's props:

 item:{
   type: monitor,
   make: HP,
   tag_number: 005
 }

The render method of my component creates and displays the textinputs thusly:

render(){
   var item_views = []
   for(index in this.props.item) {
     item_views.push(
          <View key={index} style={styles.rowContainer}>
          <Text style={styles.label}>{index} : </Text>
          <TextInput 
             style={styles.input_box}
             onSubmitEditing={(text) => this._update(index, text)}
             defaultValue={this.props.item[index].toString()}
             placeholder={index}>
          </TextInput>
          </View>
     )
   }
   return (
     <View>
     {item_views}
     </View>
   )
 }

 _update(index, text){
    //This is where I dispatch the action to change the value of "item[index]" to "text"
 }

This almost works, except that "index", which is always correctly displayed within the individual respective TextInputs in the render method, in the "_update" function ALWAYS resolves to the top key in the object, i.e. "type" in this example, no matter which text input I edit. How can I pass the correct index through textinput's onSubmitEditing function to my update function?

Upvotes: 1

Views: 1155

Answers (2)

Alessander Franca
Alessander Franca

Reputation: 2753

You can use functional programming:

render(){
   const { items } = this.props;
   return (
     <View>
     {items.map((el,index) => (
        <View key={some_id} style={styles.rowContainer}>
          <Text style={styles.label}>{index} : </Text>
          <TextInput 
             style={styles.input_box}
             onSubmitEditing={(text) => this._update(index, text)}
             defaultValue={el.toString()}
             placeholder={index}>
          </TextInput>
        </View>
     ))}
     </View>
   )
 }

 _update(index, text){
    //This is where I dispatch the action to change the value of "item[index]" to "text"
 }

Do not use index at your component key: https://reactjs.org/docs/lists-and-keys.html#keys

Upvotes: 1

Manjeet Singh
Manjeet Singh

Reputation: 4572

try to use "let" in your for loop

for(let index in this.props.item) {
     item_views.push(
          <View key={index} style={styles.rowContainer}>
          <Text style={styles.label}>{index} : </Text>
          <TextInput 
             style={styles.input_box}
             onSubmitEditing={(text) => this._update(index, text)}
             defaultValue={this.props.item[index].toString()}
             placeholder={index}>
          </TextInput>
          </View>
     )
   }

in your case index and item_views both are global object so index will always have the final value(whatever it is) within your item_views

Upvotes: 1

Related Questions