質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

1回答

1503閲覧

ReactNode (children) で 文字列を置換 (String Replace) したい場合

KazuyaKurihara

総合スコア4

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2022/06/23 11:02

[前提] React で 文字列を置換する場合

react-string-replace というライブラリーを使って、
https://github.com/iansinnott/react-string-replace

javascript

1// 疑似コードです 2import reactStringReplace from "react-string-replace" 3 4const original_string = "キーワード抽出APIはリクエストで送られたタイトルと本文からなる文書から、人名や地名、組織など文書を特徴づけるキーワードを抽出します。キーワードはタイトルや本文における出現位置や、文書中における出現回数、固有表現の種別などによってスコア付けされます。" 5 6const react_string = reactStringReplace(react_string, "キーワード", (match, i) => { 7 return( 8 <a href={"https://www.bing.com/search?q=" + match}>{match}</a> 9 ) 10}) 11 12const hogeComponent = () => { 13 return( 14 <> 15 {react_string} 16 </> 17 ) 18} 19

みたいな感じで、文字列からマッチした部分を置換できます。

React で ReactNode を置換する場合

ただ、react-string-replace だと、文字列のみしか置換できず、ReactNode を置換できないので、children のような ReactNode を react-string-replace する場合は、

javascript

1// 疑似コードです 2import React, {useEffect, useState} from "react" 3import reactStringReplace from "react-string-replace" 4import {renderToStaticMarkup} from "react-dom/server" 5 6const hogeComponent = ({children}) => { 7 8 const [content, set_content] = useState<string>("") 9 10 const mouseEnterEvent = (e) => { 11 /* popup を出す 省略 */ 12 } 13 14 const mouseLeaveEvent = (e) => { 15 /* popup を消す 省略 */ 16 } 17 18 useEffect(() => { 19 const children_string_raw = renderToStaticMarkup(React.createElement("div", {children: children})) 20 const hoge_url = "hogehoge", hoge_params = {body: "hoge"} 21 const response = await axios.post(hoge_url, hoge_params) 22 const keywords = response.data.keywords 23 let children_string; 24 keywords.forEach((keyword) => { 25 children_string = reactStringReplace(children_string_raw, keyword, (match, i) => { 26 return( 27 <a 28 href={"https://www.bing.com/search?q=" + match} 29 onMouseEnter={mouseEnterEvent} 30 onMouseLeave={mouseLeaveEvent} 31 > 32 {match} 33 </a> 34 ) 35 }) 36 }) 37 }) 38 39 return( 40 <> 41 {content} 42 </> 43 ) 44}

のように、一度 renderToStaticMarkup で ReactNode を 生の文字列 に変えてから 置換を行ってみました。

ただ 結果は、content を見ると children の HTML が反映されないことが起こってしまいました (children 内の<a>タグがそのまま表示されるなど)。
また、最終段階でもう一度 renderToStaticMarkup で children_string を文字列に変えてから、dangerouslySetInnerHTML もしてみたのですが、それだと mouseEnter と mouseLeave のイベントが消えてしまいました。

では、ReactNode を置換する場合は、どのようにすれば いいんでしょうか? ReactNode を探索するなど方法があったら、ご教授お願いできると嬉しいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

React.Children.mapで、子要素に対して関数適用が行なえます(React公式)。

  • 子要素が文字列ならreact-string-replaceを適用する
  • 子要素が別のReact要素なら、その要素のchildrenを再帰的に処理して、cloneElement()で再作成
  • 子要素がそれ以外の型だったらそのまま

のように進めればいいのではないかと考えます。

投稿2022/06/23 12:13

maisumakun

総合スコア145183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KazuyaKurihara

2022/06/24 05:28

React.Children.map は知りませんでした。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問