0

I create a <FlatList /> include <Text /> , i want to click each of the <Text /> can change this.state.

But when i click it that will show error:

this.setState is not a function

Why?

Here is my <FlatList />:

render() {
    return (
      <View>

        <FlatList
          ListHeaderComponent={() => (
            !cityArray.length ? (
              <View style={{ height: 300 }}>
                <Text style={styles.sectionTitle}>
                  Show empty message...
                </Text>
              </View>) : null
          )}
          data={cityArray}
          renderItem={this.renderItem} 
          horizontal={true}
          keyExtractor={(item, index) => index.toString()}
        />

      </View>
    );
  }

Here is my renderItem function: onPress will shows the error

renderItem({ item }) {
    return (
      <View style={styles.headerView}>
        <TouchableOpacity 
          onPress={() => {
            this.setState({ test: 'test press' });
          }}
        >
          <Text>{item.cnCity}</Text>
        </TouchableOpacity>
      </View>      
    );
  }

My this.state:

  constructor(props) {
    super(props);
    // this.renderRow = this.renderRow.bind(this);
    this.state = { tickets: [], selectedOption: '', theaters: [], test: '' };
  }

I try to creat another function:

  testPress = () => {
    this.setState({ test: 'test function' });
  }

and use it like:

renderItem({ item }) {
    return (
      <View style={styles.headerView}>
        <TouchableOpacity 
          onPress={() => {
            this.testPress();
          }}
        >
          <Text>{item.cnCity}</Text>
        </TouchableOpacity>
      </View>      
    );
  }

It still shows the same error. Why? I can't figure it out.

Any help would be appreciated.

Morton
  • 5,380
  • 18
  • 63
  • 118
  • 1
    if you want the `FlatList` to know the data change outside of the data prop, you need to set it to `extraData`, give it a try and tell me if problem exist! [Docs](https://facebook.github.io/react-native/docs/flatlist.html#extradata) – MohamadKh75 Jun 15 '18 at 04:40
  • Hey its quite a useful prompt. I try add `extraData={this.state}` under `data={cityArray}`, i though it will work, but still get the same error... – Morton Jun 15 '18 at 04:45
  • this here not referring to class it referring to renderItem function – nima moradi Jun 15 '18 at 04:48
  • @nima_moradi Sor, i don't understand what you mean `this here`. Would you mind explain again ? Thanks. – Morton Jun 15 '18 at 04:56

1 Answers1

2

check this thing
first save a ref to this

 let context;
    class s extends Component{
         constructor(props) {
        super(props);
        // this.renderRow = this.renderRow.bind(this);
        this.state = { tickets: [], selectedOption: '', theaters: [], test: '' };
        context=this;
      }

     }

and you it in onpress

  <TouchableOpacity 
      onPress={() => {
        context.setState({ test: 'test press' });
      }}
    >

why this not work?

this in js a keyword known as context and it only depend on caller, so when we call a function from other one it will use function context that there is no State in it
solution is either bind function or save reference and sometimes you can use nameless function
for more info visit How to access the correct `this` inside a callback?

nima moradi
  • 2,300
  • 21
  • 34
  • Your code is working. Thank you. But i didn't use like that before. So if i want to use `this.setState` , i must put it into some kind of react class function or i should set some variable like `let context` connect `this` . Am i right ? Thanks for your help @nima_moradi – Morton Jun 15 '18 at 05:16
  • in js this is a special keyword in function value only depends on how the function was called, you can use bind or what i did – nima moradi Jun 15 '18 at 05:26
  • 1
    check this too https://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-inside-a-callback – nima moradi Jun 15 '18 at 05:28
  • Thank you. It helps me a lot, blessing. – Morton Jun 15 '18 at 05:37