Как выделить определенное слово из текста стилем в React Native?

Я только пробую React native(да и вообще React) но обшарил всю документацию, возможно что то пропустил и не совсем понимаю как это сделать.

Есть обычное приложение. Текст подставляется из переменной(вообще приходит с апи)

import React from "react";
import {  StyleSheet, Text, View } from 'react-native';


const text = "Но повышение уровня гражданского сознания является качественно новой ступенью инновационных методов " +
    "управления процессами. Следует отметить, что понимание сути ресурсосберегающих технологий говорит о возможностях " +
    "соответствующих условий активизации. Повседневная практика показывает, что сплочённость команды профессионалов " +
    "способствует повышению качества системы массового участия."

const App = ({ }) => {

  return (
      <View style={styles.container}>
        <Text>{text}</Text>
      </View>
  )
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

export default App

Мне нужно находить определенные слова и добавлять к ним стили и тултип, находить слова не проблема я с апи могу присылать их как угодно с чем угодно, и даже завернутые в компонент, но здесь так не работает. Буду очень благодарен за подсказку в какую сторону копать.

--- Добавил --- Мне нужно выделить текст, чтобы получить что то типо такого, только из переменной

const App = ({ }) => {

        return (
            <View style={styles.container}>
                <Text>Но повышение уровня <SmartText>гражданского</SmartText> сознания является качественно <SmartText>новой</SmartText> ступенью инновационных методов " +
                    "управления процессами. Следует отметить, что понимание <SmartText>сути</SmartText> ресурсосберегающих технологий говорит о возможностях " +
                    "соответствующих условий <SmartText>активизации.</SmartText> Повседневная практика показывает, что сплочённость команды профессионалов " +
                    "способствует повышению качества системы массового участия.</Text>
            </View>
        )
    }

Чтоб я потом смог добавить выделения для слов которые в компоненте по типу примеров https://codepen.io/cbracco/pen/kNMqmJ (только естественно по тапу) или такого https://codepen.io/kshoufer/pen/yLdLPX


Ответы (3 шт):

Автор решения: Daniil Loban

В качестве примера техники приведу код на обычном реакте(решение совсестимо) и снипете(чтобы здесь отобразилось),

Делаем 2 компонента:

  • AllText (для обработки и вывода всего текста)
  • Selected (для стилизации выделения)

Тест разбивается словами и все что между попадает в массив separators (вот пример массива: [ "", " ", "!", ", "], чтобы не мешали знаки разделители а так же другие символы и чтобы они не потерялись после преобразований), позже из этого массива происходит заполнение между словами ( + separators[i+1]).

Сразу оговорюсь - код еще нужно допиливать (в частности возможно регулярки), моя цель была показать решение минимумом кода.

window.Fragment = React.Fragment
window.useState = React.useState
window.useEffect = React.useEffect

// основной код
// массив слов для выделения
const selectedWords = ["это", "этом", "обработать"]
// пример текста
const text = "в этом тесте, который нужно обработать, нужно выделить это и это"

// это компонент выделенного слова
const Selected = ({text}) => <b style={{color: 'red'}}>{text}</b>

// это компонент для всего текста
const AllText = ({text}) => {

  const [separators, setSeparators] = useState([])
  useEffect(()=>{
    // нужно уточнить регулярку 
    setSeparators(text.split(/[А-яё0-9A-z]+/))
  },[])

  return (
    <Fragment>
    {
       text.split(/[^А-яё0-9A-z]+/).map((e, i) => 
         (selectedWords.includes(e)) 
           ? <Selected key={e + i} text={e + separators[i+1]} /> 
           : <Fragment key={e + i}>{ e + separators[i+1]}</Fragment>
       )
    }
    </Fragment>
  )
}  

// тут мы каким либо образом получаем 
// и передаем текст в компонент
const App = () => {
  return (
      <AllText text={text}/> 
  );
};

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin ></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin ></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<div id="root">

→ Ссылка
Автор решения: Виктор

Я возможно сделал не самым лучшим образом но спасибо @Daniil Loban за подсказку и ответ) оставлю и свою решение, вдруг кому пригодится

import {StyleSheet, Text} from 'react-native';
import React from "react";

let string = "Во время разработки я собираюсь использовать базу данных SQLite. База данных SQLite являются наиболее удобным выбором для разработки небольших приложений даже очень маленьких, так как каждая база данных хранится в одном файле на диске и нет необходимости запускать сервер базы данных, как MySQL и PostgreSQL."


const TestOutput = () => {
    // Создаю переменную для перебора
    let i = 0
    // Разбиваю строку на массив
    let array = string.split(' ');
    
    const map = Array.prototype.map
    // Здесь я перебираю массив и использую переменную i для индекса (не совсем понял как забирать индексы если они есть)
    const newName = map.call(array, eachLetter => {
        i++
        // Если элемент НЕ 10 по списку то добавляю пробел и возвращаю в массив
        if (i % 10 !== 0) {
            return `${eachLetter} `
        // А вот здесь беру каждый 10 элемент массива и добавляю пробел и красный цвет    
        }else{
            return <Text style={styles.red}>{eachLetter} </Text>
        }
    })

    return (
        <Text>{newName}</Text>
    )
}

const styles = StyleSheet.create({
    red: {
        color: '#ff0000'
    },
});

export default TestOutput
→ Ссылка
Автор решения: Eduard Konovka

Создаём компонент InlineText.jsx:

import React, { Fragment } from 'react';
import { View, Text, StyleSheet } from 'react-native';

export default function InlineText({ list, styleContainer }) {
  return (
    <View style={[styles.container, styleContainer]}>
      {list.map((stringWrapper, idx) => {
        const arr = stringWrapper.string.split(' ');
        return (
          <Fragment key={new Date().getTime() + idx}>
            {arr.map((word, idx) => (
              <Text key={word + idx} style={stringWrapper.style}>
                {word}
              </Text>
            ))}
          </Fragment>
        );
      })}
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'row',
    flexWrap: 'wrap',
  },
});

И вызываем его в вашем коде:

<InlineText
  list={[
    {
      string: 'Первая текстовая строка, ',
      style: {
        fontSize: 16,
        color: '#FF0000',
        marginRight: 5,
      },
    },
    {
      string: 'к первой добавляем вторую строку, ',
      style: {
        fontSize: 16,
        color: '#00FF00',
        marginRight: 5,
      },
    },
    {
      string: 'а ко второй - третью, и так дале - сколько нужно.',
      style: {
        fontSize: 16,
        color: '#0000FF',
        marginRight: 5,
      },
    },
  ]}
  styleContainer={{ marginLeft: 18 }}
/>

→ Ссылка