Как я могу использовать регулярные выражения для добавления события onclick к словам текста в React?

#javascript #reactjs

Вопрос:

Я пытаюсь использовать регулярные выражения, чтобы добавить событие onclick ко всем словам текста в React. До сих пор я пытался сделать это двумя разными способами, но ни один из них не сработал. Сначала я попробовал:

 return(
   <div>
      <p>{textString.replace(/w /g,`<span onClick=handleSearch('$amp;')>$amp;</span>`)}</p>
   </div>
)
 

«Текстовая строка» — это строка с текстом.
С помощью этой попытки мне удалось добавить событие onclick к словам, но весь результат находится внутри новой строки, поэтому теги span отображаются на странице.

После этого я попытался использовать innerHTML.

 useEffect(() =>{
   let text = textString.replace(/w /g,`<span onClick=handleSearch('$amp;')>$amp;</span>`)
   document.getElementById('text-placeholder').innerHTML = text
},[])

return(
   <div>
      <p id="text-placeholder">Placeholder</p>
   </div>
)
 

Эта попытка сработала немного лучше. Мне удалось добавить событие onclick ко всем словам, и все правильно отображается на странице. Однако, когда я нажимаю на слово, я получаю следующую ошибку в консоли.

«Ошибка неперехваченной ссылки: handleSearch не определен в HTMLSpanElement.onclick»

Я не знаю, что означает эта ошибка, но функция не работает.

Кто-нибудь знает, как я могу использовать регулярные выражения для добавления события onclick к каждому слову текста?

Ответ №1:

Вам нужно создать новые элементы JSX вместо строк с .replace помощью . Сопоставьте слова или не-слова и вместо этого сопоставьте их с массивом.

 return (
    <div>
        <p>{
            textString
            .match(/w |W /g)
            .map(match => (
                /W/.test(match)
                    ? match // plain string
                    : <span onClick={() => handleSearch(match)}>{match}</span> // JSX element
            ))
        }</p>
    </div>
)
 

ДЕМОНСТРАЦИЯ:

 const handleSearch = str => console.log('searching', str);
const textString = 'foo bar ###';
const App = () => {
    return (
        <div>
            <p>{
                textString
                .match(/w |W /g)
                .map(match => (
                    /W/.test(match)
                        ? match // plain string
                        : <span onClick={() => handleSearch(match)}>{match}</span> // JSX element
                ))
            }</p>
        </div>
    )
};

ReactDOM.render(<App />, document.querySelector('.react')); 
 <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div class='react'></div>