7

I did render following kind of list with onPress "handler".

enter image description here

I have realised that onPress handler is useless because I cannot get the reference of race pressed. I get ref is not defined error.

var races = Engine.possibleRaces;

function racePressed(ref) {
    console.log("REF: " + ref); // is never called
}

var races = Engine.possibleRaces;
var rowViews = [];
for (var i = 0; i < races.length; i++) {
  rowViews.push(
    <Text
      ref={i}
      onPress={() => racePressed(ref)} // ref is not defined
      style={styles.raceText}>{races[i].text}
    </Text>

  );
}

<View style={{width: Screen.width, flexDirection:'row', flexWrap: 'wrap', alignItems: "center"}}>
       {rowViews}
</View>  

I did also try to pass i as a parameter. It did not work, because it has the value after iteration ends. Basically it has races.length value.

  onPress={() => racePressed(i)} // Same as races.length

Edit:

I did isolate problem to following program.

'use strict';
import React, {
  AppRegistry,
  Component,
  StyleSheet,
  Text,
  View
} from 'react-native';

let texts = [{text: "Click wrapper text1"}, {text: "Click wrapper text2"}];

class sandbox extends Component {

  rowPressed(ref, i) {
    console.log("rowPressed: " + ref + " " + i)
  }

  render() {

    var rows = [];

    for (var i = 0; i < texts.length; i++) {
      rows.push(
        <Text
          ref={i}
          onPress={() => this.rowPressed.bind(this, i)}
          style={styles.raceText}>{texts[i].text}
        </Text>
      );
    }

    return (
      <View style={styles.container}>

        <View>
          {rows}
        </View>

      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center'
  }
});

AppRegistry.registerComponent('sandbox', () => sandbox);

Callback is not called and no errors thrown except following warning

[tid:com.facebook.React.JavaScript] Warning: Each child in an array or iterator should have a unique "key" prop. Check the render method of `sandbox`. See https://fb.me/react-warning-keys for more information.
Markku
  • 555
  • 1
  • 8
  • 15

2 Answers2

12

I suggest you bind that function in constructor like..

constructor(props){
    super(props);
    //your codes ....

    this.rowPressed = this.rowPressed.bind(this);
}

This binds this context of rowPressed function as you expect it to be, making your code works properly.

Also, to get rid of warning messages you should provide unique key properties for each <Text> element, using <Text key={i} ....> in your code should work.

Adrian Seungjin Lee
  • 1,646
  • 2
  • 15
  • 28
  • Could you share a bit more code. How should I change following code to the access to "this"? `render: function() { function rowPressed(id) { // Cannot read property 'state' of undefined this.state.races[id].chosen != this.state.races[id].chosen; } this.rowPressed = this.rowPressed.bind(this); ... onPress={() => rowPressed(i)}` – Markku Mar 01 '16 at 05:49
3

I try to do something similar and found this solution :

render() {
    var _data = texts;
    return (
        <View style={styles.container}>
        { _data.map(function(object,i) {
            return (
                <Text ref={i}
                  onPress={() => this.rowPressed(i)}
                  style={styles.raceText}>{texts[i].text}
                </Text> );
            })
        }
        </View>
    );
}

Cheers

cdcl
  • 69
  • 1
  • 2
  • 1
    I cannot use "this" expression in "this.rowPressed(i)" else I get "Cannot read property 'rowPressed' of undefined". I just need to use rowPressed and function is properly called. Now I have issue with the rowPressed function. I cannot get access to this.state anymore. `function rowPressed(id) { this.state... // Cannot read property 'state' of undefined }` – Markku Mar 01 '16 at 05:43
  • Following seems to work, but for some reason it feels not being properly done. `var that = this; function rowPressed(id) { that.state.races[id].chosen = !that.state.races[id].chosen;` – Markku Mar 01 '16 at 06:01