saving dynamic refs to array in class component in react-native only saves last index

Viewed 32

i have a class component with dynamically created views and i want to access those views refs so i decided to save all refs in array of objects to access them later. but whenever i try to access the refs it always refer to last index, meaning map index is always equal last value only.

here is an example to demonstrate the behavior


import React, {Component} from 'react';
import {View, Text, TextInput, Button} from 'react-native';

class myComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }

  data = [1, 2, 3];

  inputsRefs = new Array(3).fill({
    input1: null,
    input2: null,
    index: null,
  });

  async componentDidMount() {}

  render() {
    return (
      <View>
        {this.data.map((x, i) => {
          this.inputsRefs[i].index = i;
          return (
            <View key={i+''}>
              <TextInput ref={ref => (this.inputsRefs[i].input1 = ref)} />
              <TextInput ref={ref => (this.inputsRefs[i].input2 = ref)} />
            </View>
          );
        })}

        <Button
          title="print indexes"
          onPress={() => {
            console.log(this.inputsRefs.map(x => x.index));
            //the result is [2,2,2] while it should be [0,1,2]
          }}
        />
      </View>
    );
  }
}

export default myComponent;

edit Adding key did not affect the outcome results

1 Answers

Try to set the key prop inside of map loop. So here is the render method:

  ...
  render() {
    return (
      <View>
        {this.data.map((x, i) => {
          this.inputsRefs[i].index = i;
          return (
            <View key={`key-${i}`}>
              <TextInput ref={ref => (this.inputsRefs[i].input1 = ref)} />
              <TextInput ref={ref => (this.inputsRefs[i].input2 = ref)} />
            </View>
          );
        })}

        <Button
          title="print indexes"
          onPress={() => {
            console.log(this.inputsRefs.map(x => x.index));
            //the result is [2,2,2] while it should be [0,1,2]
          }}
        />
      </View>
    );
  }
...
Related