skip to Main Content

I am trying to figure out a way to change the styling of multiple words each wrapped in a Text component in React Native, using an onPress event on each word.

I know how to do this in vanilla Javascript by running .split(" ") on a string to separate the words, and then mapping through them and wrapping them all in HTML elements like span tags with the word (in lowercase) as the class name and adding an onclick event that passes in the word .toLowerCase() as an argument to a function, which adds the word to an array of highlighted words, and then toggles adding or removing a class which will result in changing the styling of each instance of that word in a page.

The function would be something like this:

function exampleFunction(theWord) {

  let temp = document.getElementsByClassName(theWord)

  for (i = 0; i < temp.length; i++) {
    if (temp[i].classList.contains("highlighted")) {
      if (i === 0) {
        let filteredArray = highlightedWords.filter((e) => e !== theWord)

        highlightedWords = filteredArray
      }

      temp[i].classList.remove("highlighted")
    } else {
      if (i === 0) {
        highlightedWords.push(theWord)
      }

      temp[i].classList.add("highlighted")
    }
  }
}

But the problem is that React Native doesn’t seem to use classes. And I am very new to React Native. So I am lost as to how to approach this issue.

Any help is greatly appreciated.

2

Answers


  1. React uses a declarative instead of an imperative API as used in the DOM.
    Therefore you should declare state which is the index of currently highlighted word (you can use a negative value to indicate that no word is highlighted). Then add the class highlighted only when the index of the word and the index in your state match. If one clicks on the same value again set the highlighted to a negative value again. React will automatically re-re-render whenever you update the state using setHighlighted().

    const Sentence = ({ words }) => {
      const [highlighted, setHighlighted] = React.useState(-1);
      
      return (
        <React.Fragment>
          {words.map((word, index) => (
            <p key={word} 
               onClick={() => setHighlighted(highlighted === index ? -1: index)} 
               className={index === highlighted && "highlighted"}
               >
               {word}
            </p>
          ))}
        </React.Fragment>
      );
    };
    
    ReactDOM.render(<Sentence words={["some ", "random ", "words."]}/>, document.getElementById('root'));
    .highlighted {
      color: blue;
      background: red;
    }
    <script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
    <div id="root"></div>
    Login or Signup to reply.
  2. For react native , umm you cant do like that.

    https://snack.expo.dev/ug8zEbrWZ

    Please check working example above, and also do check out code here

    import * as React from 'react';
    import { Text, View, StyleSheet } from 'react-native';
    import Constants from 'expo-constants';
    
    // You can import from local files
    import AssetExample from './components/AssetExample';
    
    // or any pure javascript modules available in npm
    import { Card } from 'react-native-paper';
    
    function getRandomColor() {
      var letters = '0123456789ABCDEF';
      var color = '#';
      for (var i = 0; i < 6; i++) {
        color += letters[Math.floor(Math.random() * 16)];
      }
      return color;
    }
    
    export default function App() {
    
      const [fC,setFc] = React.useState(getRandomColor())
      const [sC,setSc] = React.useState(getRandomColor())
      const [tC,setTc] = React.useState(getRandomColor())
      const [zC,setZc] = React.useState(getRandomColor())
    
      return (
        <View style={styles.container}>
        <View style={{flexDirection:'row'}}>
          <Text 
          onPress={() => setFc(getRandomColor())}
          style={[styles.eachStyle,{
            color:fC
          }]} >hey</Text>
          <Text
           onPress={() => setSc(getRandomColor())}
            style={[styles.eachStyle,{
            color:sC
          }]}>this</Text>
          <Text 
           onPress={() => setTc(getRandomColor())}
           style={[styles.eachStyle,{
            color:tC
          }]}>is</Text>
          <Text 
           onPress={() => setZc(getRandomColor())}
           style={[styles.eachStyle,{
            color:zC
          }]}>great</Text>
          </View>
        </View>
      );
    }
    
    const styles = StyleSheet.create({
    
      eachStyle:{
        marginHorizontal:3
      },
    
      container: {
        flex: 1,
        justifyContent: 'center',
        paddingTop: Constants.statusBarHeight,
        backgroundColor: '#ecf0f1',
        padding: 8,
      },
      paragraph: {
        margin: 24,
        fontSize: 18,
        fontWeight: 'bold',
        textAlign: 'center',
      },
    });
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search