简体   繁体   中英

React Native - How do I know which dynamic Component was pressed?

I'm new to React Native and am creating a screen with several Switches, the number and specifics of which aren't known until runtime.

In the onValueChange callback, the new value of the Switch is passed in, but how can I identify which Switch was actually pressed? (code simplified)

export default class Class1 extends Component
{
    switchhit(newval)
    {
        console.log('*How do I know which switch was hit?* newval=' + newval);
    }

    render()
    {
        let ii, arrC = [];

        for (ii = 0; ii < sSettChcs.length; ii++)
        {
            let jsx0 =
                <View>
                    <View>
                        <Text>{ sSettChcs[ii] }</Text>
                        <Text>{ sSettDesc[ii] }</Text>
                    </View>
                    <View>
                        <Switch 
                            onValueChange = { (newval) => this.switchhit(newval) }
                            value = { true } />
                    </View>
                </View>;
            arrC.push(jsx0);
        }

        let jsx =
            <ScrollView>{ arrC }</ScrollView>;
        return jsx;
    }
}

Note that this is a simplified example and the final screen will have Components of type TextInput , Picker , etc. so my question isn't really specific to just Switch .

With some help here I found that a straightforward way to do this is to "subclass" via composition your component ( Switch in this case) and store an identifier ( idx0 below):

class MySwitch extends Component
{
    swbang(newval)
    {
        console.log('newval=' + newval + 'idx0=' + this.props.idx0);
    }

    render()
    {
        return (
          <View>
            <Switch 
                onValueChange = { (newval) => this.swbang(newval) }
                value = { true } />
          </View>
        );
    }
}

The original code then becomes:

export default class Class1 extends Component
{
    render()
    {
        let ii, arrC = [];

        for (ii = 0; ii < sSettChcs.length; ii++)
        {
            let jsx0 =
                <View>
                    <View>
                        <Text>{ sSettChcs[ii] }</Text>
                        <Text>{ sSettDesc[ii] }</Text>
                    </View>
                    <View>
                        <MySwitch idx0 = { ii } />
                    </View>
                </View>;
            arrC.push(jsx0);
        }

        let jsx =
            <ScrollView>{ arrC }</ScrollView>;
        return jsx;
    }
}

Simple in retrospect but nonintuitive coming from a Java/C type world.

I'm sure this can be done better and that certain aspects don't conform to React Native style, but this demonstrates the concept.

A possible solution (but I don't think that it's the best one), would be to initialize an array of values which contain some sort of a unique id in the componentDidMount method:

componentDidMount() {
  const data = [];

  // You'll probably need to set this sSettChcs array in the state
  for (i = 0; i < sSettChcs.length; i++) {
    data.push({ id: i, value: false });
  }

  this.setState({ data });
}

And then rewrite your switchint function to look something like this:

switchhit(newval, id)
{
    const newData = [];

    this.state.data.forEach(val => { 
      if (val.id === id) {
        newData.push({ id, value: newval });
      } else {
        newData.push(val);
      }
    });

    this.setState({ data: newData });
}

And then, in render:

for (ii = 0; ii < this.state.data.length; ii++)
    {
        let jsx0 =
            <View>
                <View>
                    <Text>{ sSettChcs[ii] }</Text>
                    <Text>{ sSettDesc[ii] }</Text>
                </View>
                <View>
                    <Switch 
                        onValueChange = { (newval) => this.switchhit(newval, this.state.data[ii].id) }
                        value = { this.state.data[ii].value } />
                </View>
            </View>;
        arrC.push(jsx0);
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM