3

I want to set different click listeners on different words of . Currently what i have is

<Text>Android iOS React Native<Text>

Now i want to know when user click on Android, iOS and React Native, i have to perform some analytics on that so need click listeners for seperate words.

Does any one have idea about it? I have checked this thread but i din't found it useful for my requirement.

Update String i have given is just an example string, in real time i will be getting dynamic strings.

This is what i will be getting as dynamic string

{
    "str":"Hi i am using React-Native, Earlier i was using Android and so on"
    "tagWords":["React-Native","Android"]
}

And in output i want, "Hi i am using React-Native, Earlier i was using Android and so on"

with click event on "React-Native" and "Android". Is is possible?

Ravi
  • 34,851
  • 21
  • 122
  • 183

3 Answers3

7

The post you sent is the simplest way you can achieve the desired behavior. Sinse you need to have different listeners you need to implement different Text components.

Example

export default class App extends Component {
  onTextPress(event, text) {
    console.log(text);
  }
  render() {
    return (
      <View style={styles.container}>
        <Text>
          <Text onPress={(e) => this.onTextPress(e, 'Android')} style={styles.red}>{'Android '}</Text>
          <Text onPress={(e) => this.onTextPress(e, 'iOS')} style={styles.purple}>{'iOS '}</Text>
          <Text onPress={(e) => this.onTextPress(e, 'React Native')} style={styles.green}>{'React Native'}</Text>
        </Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center'
  },
  red: {
    fontSize: 20,
    color: 'red'
  },
  purple: {
    fontSize: 20,
    color: 'purple'
  },
  green: {
    fontSize: 20,
    color: 'green'
  }
});

Update 1 (Dynamic text)

  render() {
    const fixedString = 'I\'m a fixed string that slipleted';
    const arrayOfStrings = ['These', 'are', 'strings', 'from', 'array'];
    return (
      <View style={styles.container}>
        <Text style={styles.textContainer}>
        {
          fixedString.split(' ').map((str, index) => {
            return (
              <Text onPress={(e) => this.onTextPress(e, str)}>
                {`${str}${index !== (fixedString.split(' ').lenght -1) && ' '}`}
              </Text>
            )
          })
        }
        </Text>
        <Text style={styles.textContainer}>
        {
          arrayOfStrings.map((str, index) => {
            return (
              <Text onPress={(e) => this.onTextPress(e, str)}>
                {`${str}${index !== (arrayOfStrings.lenght -1) && ' '}`}
              </Text>
            )
          })
        }
        </Text>
      </View>
    );
  }

Update 2 (for example dynamic data)

  removePunctuation = (text) => {
    // this is a hack to remove comma from the text
    // you may want to handle this different
    return text.replace(/[.,\/#!$%\^&\*;:{}=\_`~()]/g,"");
  }
  render() {
    const arrayOfObjects = [{
      str: 'Hi i am using React-Native, Earlier i was using Android and so on',
      tagWords: ['React-Native', 'Android']
    }];
    return (
      <View style={styles.container}>
        <Text style={styles.textContainer}>
          {
            arrayOfObjects.map((obj) => {
              return obj.str.split(' ').map((s, index) => {
                if ( obj.tagWords.indexOf(this.removePunctuation(s)) > -1 ) {
                  return (
                    <Text onPress={(e) => this.onTextPress(e, s)} style={styles.red}>
                      {`${s} ${index !== (obj.str.split(' ').lenght - 1) && ' '}`}
                    </Text>
                  )
                } else return `${s} `;
              })
            })
          }
        </Text>
      </View>
    );
  }
bennygenel
  • 23,896
  • 6
  • 65
  • 78
  • String i have given is just an example, i am having dynamic string, so how can i perform that, i know by using 3 `` we can do it, but how can we do it with dynamic string? – Ravi Nov 06 '17 at 06:28
  • @RaviRupareliya updated question with dynamic text example but I must say if the text is long or if you have lots of listeners like these you may have some performance issues since every word creates a new listener and a new function. – bennygenel Nov 06 '17 at 06:46
  • @bennygenel you explained that pretty well, performace issues will be there. An exact scenario will help us giving a proper answer. – Devansh sadhotra Nov 06 '17 at 06:54
  • @devanshsadhotra exact scenario is i might have string like "Hi i am using React-Native, Earlier i was using Android and so on" where words "React-Native" and "Android" i will be getting in seperate array so i have to perform actions based on that. – Ravi Nov 06 '17 at 07:03
  • So , is there any specific set of words over which you want to perform some action? – Devansh sadhotra Nov 06 '17 at 07:07
  • @RaviRupareliya can you update your question with a better representation of your example. like how does your dynamic data look like, which part are dynamic etc. – bennygenel Nov 06 '17 at 07:08
  • @bennygenel sorry for misleading, i have updated my question. – Ravi Nov 06 '17 at 07:16
2

all you need to use is TouchableOpacity(for the tap effect and clicks), View for the alignment of texts. and certain styling. I am providing you the code snippet that will work for you , all other syntax will remain same

import {Text, View, TouchableOpacity} from 'react-native'
<View style={{flexDirection:'row'}}>
  <TouchableOpacity onPress={{()=>doSomethingAndroid()}}>
        <Text>Android</Text>
  </TouchableOpacity>
  <TouchableOpacity onPress={{()=>doSomethingiOS()}}><Text> iOS</Text> 
  </TouchableOpacity>
  <TouchableOpacityonPress={{()=>doSomethingReactNative()}}><Text> React Native</Text>
  </TouchableOpacity>
</View>

i hope this works, comment back if any issue happens

Devansh sadhotra
  • 1,495
  • 1
  • 18
  • 41
  • String i have given is just an example, i am having dynamic string, so how can i perform that, i know by using 3 `` we can do it, but how can we do it with dynamic string? – Ravi Nov 06 '17 at 06:28
  • if the value is coming from backend , then you must do like, : {operatingSystem} in operatingSystem key u must fetch the desired value. – Devansh sadhotra Nov 06 '17 at 06:41
1

You can wrap each clickable words into 'TouchableOpacity' component, and tract the onPress event as follows

<View style={{flexDirection: 'row'}}>
   <TouchableOpacity onPress={() => {
        console.log('Android Clicked');
      }}>
      <Text>Android</Text>
   </TouchableOpacity>
   <TouchableOpacity onPress={() => {
       console.log('iOS Clicked');
     }}>
     <Text>Ios</Text>
   </TouchableOpacity>
</View>

Please do adjust the spacing between words.

Edit: For dynamic string you can proceed as follows

...

handleWordClick(str, handler) {
 var words = str.split(' '), // word separator goes here,
     comp = [];
 words.forEach((s, ind) =>{
     comp.push(
       <TouchableOpacity key={ind} onPress={() => handler.call(this, s)}>
          <Text>{s}</Text>
       </TouchableOpacity>
       );
 })
 return comp;
}

render() {
  var comp = this.handleWordClick('Android iOS React-Native', (word) => {
      //handle analytics here...
      console.log(word);
      });
  return (
    <View>
     ...
     <View style={{flexDirection: 'row'}}>
       {comp}
     </View>
     ...
     </View>
    )
}

I am not sure what will be your word separator as the example you have given has 'React Native' as single word. Please pay attention on this part.

Hope this will help you.

Prasun
  • 4,943
  • 2
  • 21
  • 23
  • String i have given is just an example, i am having dynamic string, so how can i perform that, i know by using 3 `` we can do it, but how can we do it with dynamic string? – Ravi Nov 06 '17 at 06:28
  • @RaviRupareliya I have edited my answer for dynamic string, I am not sure whether it will serve your purpose or not, but expecting this will help you. – Prasun Nov 06 '17 at 06:57