Alex
Alex

Reputation: 1505

Know the component that called a function

I want to dynamically create UI elements such as: https://facebook.github.io/react-native/docs/picker.html based on JSON data.

<Picker
  selectedValue={this.state.language}
  onValueChange={(lang) => this.setState({language: lang})}>
  <Picker.Item label="Java" value="java" />
  <Picker.Item label="JavaScript" value="js" />
</Picker>

Using this boilerplate I see two problems:

First: I cannot distinguish between the Picker component that called the method. Is there a way in JavaScript to know which component called a certain function? (I am a JS noob and could not find anything helpful about this)

Second: The selectedValue property is bound to the state. How would I go about doing this in my case where I create Picker elements on the fly. I do not want to explicitly call each component and update this property but the way it works now is not great. Removing this property does not display the last selected item but the topmost in the list.

Upvotes: 1

Views: 79

Answers (1)

Ismailp
Ismailp

Reputation: 2383

You would need to keep state for each value for each <Picker> component. There are multiple ways of doing that. One way is:

<Picker
  selectedValue={this.state.picker1}
  onValueChange={(lang) => {
    let state = this.state;
    state['picker1'] = val;
    this.setState(state);
  }}>
  <Picker.Item label="Java" value="java" />
  <Picker.Item label="JavaScript" value="js" />
</Picker>

Example code

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

export default class DemoProject extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }

  _renderInputs() {
    const inputCount = 4;
    const inputs = [];
    for (let i = 0; i < inputCount; i++) {
      const stateValueIdentifier = 'text' + i;
      inputs.push(
        <TextInput
          style={styles.inputStyle}
          key={'text-input-' + i}
          onChangeText={(text) => {
            let state = this.state;
            state[stateValueIdentifier] = text;
            this.setState(state)
          }}
          value={this.state[stateValueIdentifier]}
        />
      )
    }
    return inputs;
  }

  render() {
    return (
      <View style={styles.container}>
        <Text>test</Text>
        {this._renderInputs()}
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'column'
  },
  inputStyle: {
    height: 40, 
    borderColor: 'gray', 
    borderWidth: 1, 
    flex: 1
  }
});

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

Upvotes: 1

Related Questions