Как выделить определенное слово из текста стилем в 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 шт):
В качестве примера техники приведу код на обычном реакте(решение совсестимо) и снипете(чтобы здесь отобразилось),
Делаем 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
Создаём компонент 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 }}
/>