React: 文字列の䞀郚をコンポヌネントに眮き換える方法は

䜜成日 2015幎03月12日  Â·  40コメント  Â·  ゜ヌス: facebook/react

私は明らかに機胜しおいないこのコヌドを持っおいたす

    _.each(matches, (match) ->
      string = string.replace(match, ->
        <span className="match" key={i++}>{match}</span>
      )
    )

これは、文字列がオブゞェクトず混圚する結果になるためです。 悪い私は知っおいたす。 しかし、どうすれば文字列内にReactコンポヌネントを远加できたすか 私が欲しいのは、reactコンポヌネントで文字列の䞀郚を匷調衚瀺するこずです。 クラックするのは難しいケヌスだず思いたす。

最も参考になるコメント

split関数を正芏衚珟で䜿甚しおから、次のようにキャプチャされたパヌツを眮き換えるこずができたす。

var parts = "I am a cow; cows say moo. MOOOOO.".split(/(\bmoo+\b)/gi);
for (var i = 1; i < parts.length; i += 2) {
  parts[i] = <span className="match" key={i}>{parts[i]}</span>;
}
return <div>{parts}</div>;

䞍明な点がある堎合はお知らせください。

党おのコメント40件

このようなものが機胜するはずです

const escapeRE = new RegExp(/([.*+?^=!:$(){}|[\]\/\\])/g)
const safeRE = (string) => {
  return string.replace(escapeRE, "\\$1")
}

class Hightlight extends Component {
  static propTypes = {
    match : PropTypes.string,
    string : PropTypes.string,
  }

  render() {
    return (
      <span
        dangerouslySetInnerHTML={{
          __html : string.replace(safeRE(this.props.match), "<strong className\"match\">$1</strong>")
        }} />
    )
  }
}

はい、私はdangerouslySetInnerHTMLを悪甚するこずを考えおいたしたが、この考えは奜きではありたせん。 この方法は、正圓な理由で危険ずラベル付けされおいたす。

文字列内のjsxを解析するようにReactに教える方法はありたせんか ReactにiEを解析させる

var example = "this one word <span className="match" key={i++}>hello</span> is highlighted"

そしおこれをrenderメ゜ッドで返したすか

@binarykitchen React芁玠を動的に構築できたす。これをここで行う必芁がありたす。文字列の眮換だけでは、それを行うこずはできたせん。

@syranideはい、私はすでにそれを知っおいたす。 私のポむントは、これは玠晎らしいJSX / React機胜ではないかずいうこずです。 文字列を解析し、内郚のタグを子Reactコンポヌネントに倉換したす。

split関数を正芏衚珟で䜿甚しおから、次のようにキャプチャされたパヌツを眮き換えるこずができたす。

var parts = "I am a cow; cows say moo. MOOOOO.".split(/(\bmoo+\b)/gi);
for (var i = 1; i < parts.length; i += 2) {
  parts[i] = <span className="match" key={i}>{parts[i]}</span>;
}
return <div>{parts}</div>;

䞍明な点がある堎合はお知らせください。

実行時のJSXの解析ぱラヌが発生しやすく、時間がかかり、セキュリティに圱響を䞎える可胜性がありたす。本質的に、dangerlySetInnerHTMLよりも安党ではありたせん。

掻字ケヌスでは少し問題になる可胜性がありたす

— mlb

12の火星2015幎、午埌9時37分で、ベン・アルパヌト[email protected]は曞きたした

分割関数を正芏衚珟で䜿甚しおから、次のようにキャプチャされたパヌツを眮き換えるこずができたす。

var Parts = "私は牛です。牛はmooず蚀いたす。MOOOOO。"。split/\ bmoo + \ b/ gi;
forvar i = 1; i <parts.length; i + = 2{
パヌツ[i] = ;}戻る

{郚品}
;
䞍明な点がある堎合はお知らせください。

—
このメヌルに盎接返信するか、GitHubで衚瀺しおください。

プログラムで文字列の䞀郚を匷調衚瀺しようずしたずきにも、この問題が発生したした぀たり、 <span>タグに眮き換えたす。 䞊蚘の@spicyjの゜リュヌションに基づいおモゞュヌルを䜜成するこずになりたした。 興味のある人のために iansinnott / react-string-replace

@iansinnottそれを共有しおくれおありがずう。 私は完党な必芁がありそうだが実珟し、それを䜿甚し始めたString.prototype.replace 眮き換える関数内で正芏衚珟のための個別のマッチンググルヌプぞのアクセスを必芁ずしたAPIを。 倉曎は単玔なパッチ以䞊のものになるそしおAPIの倉曎が必芁になるこずに気付いたので、新しいリポゞトリを䜜成したした https 

react-string-replaceが芁件に合わない堎合

https://github.com/EfogDev/react-process-string

以䞋は、テキスト文字列内のキヌワヌドを匷調衚瀺する方法ずしお機胜したした。
危険なHTMLの蚭定

/**
 * Find and highlight relevant keywords within a block of text
 * <strong i="7">@param</strong>  {string} label - The text to parse
 * <strong i="8">@param</strong>  {string} value - The search keyword to highlight
 * <strong i="9">@return</strong> {object} A JSX object containing an array of alternating strings and JSX
 */
const formatLabel = (label, value) => {
  if (!value) {
    return label;
  }
  return (<span>
    { label.split(value)
      .reduce((prev, current, i) => {
        if (!i) {
          return [current];
        }
        return prev.concat(<b key={value + current}>{ value }</b>, current);
      }, [])
    }
  </span>);
};

formatLabel('Lorem ipsum dolor sit amet', 'dolor');
// <span>Lorem ipsum <b>dolor</b> sit amet</span>

耇数の倀をラップできるように、いく぀かのパタヌンに䞀臎する蚀及のためにこのようなものが必芁であり、 @ richardwestenra゜リュヌションにいく぀かの倉曎を加えたした。 倚分それは誰かのために圹立぀でしょう。

/**
 * Find and highlight mention given a matching pattern within a block of text
 * <strong i="7">@param</strong> {string} text - The text to parse
 * <strong i="8">@param</strong> {array} values - Values to highlight
 * <strong i="9">@param</strong> {RegExp} regex - The search pattern to highlight 
 * <strong i="10">@return</strong> {object} A JSX object containing an array of alternating strings and JSX
 */
const formatMentionText = (text, values, regex) => { 
    if (!values.length)
        return text;

    return (<div>
        {text.split(regex)
            .reduce((prev, current, i) => {
                if (!i)
                    return [current];

                return prev.concat(
                    values.includes(current)  ?
                        <mark key={i + current}>
                            {current}
                        </mark>
                        : current
                );
            }, [])}
    </div>);
};

const text = 'Lorem ipsum dolor sit amet [[Jonh Doe]] and [[Jane Doe]]';
const values = ['Jonh Doe', 'Jane Doe'];
const reg = new RegExp(/\[\[(.*?)\]\]/); // Match text inside two square brackets

formatMentionText(text, values, reg);
// Lorem ipsum dolor sit amet <mark>Jonh Doe</mark> and <mark>Jane Doe</mark>

同様の問題があり、reactポヌタルで解決したした。ノヌドを簡単に芋぀けるために、文字列をdivに眮き換え、createPortalを䜿甚しおreactコンポヌネントをそのdivにレンダリングしたした。

@rmtnghなぜあなたがそれをする必芁があるのか​​興味がありたす。 やり過ぎかもしれないようです。 非反応コヌドをむンタヌレヌスしおいたすか

この問題の解決策に぀いおは、 string-replace-to-arrayお勧めしたす私は著者です。 これは、耇数の環境での戊いず時間のテストが行​​われおいたす。 たた、非垞に小さいですラむブラリ党䜓がこのファむルhttps://github.com/oztune/string-replace-to-array/blob/master/string-replace-to-array.jsです。

正芏衚珟を䜿甚した䜿甚䟋を次に瀺したす。

import replace from 'string-replace-to-array'

// The API is designed to match the native 'String.replace',
// except it can handle non-string replacements.
replace(
  'Hello Hermione Granger...',
  /(Hermione) (Granger)/g,
  function (fullName, firstName, lastName, offset, string) {
    return <Person firstName={ firstName } lastName={ lastName } key={ offset } />
  }
)

// output: ['Hello ', <Person firstName="Hermione" lastName="Granger" key={ 0 } />, ...]

@oztune返信ありがずうございたす。この堎合、CMSのwysiwyg゚ディタヌからの䞀連のhtmlマヌクアップがあり、そのマヌクアップ内の特定の堎所に反応コンポヌネントを配眮したいず思いたす。
ポヌタルを䜿甚するよりもラむブラリを䜿甚する方が良いず思いたすか ポヌタルが行うこずは、通垞のコンポヌネントをレンダリングするよりも費甚がかからない最も近いノヌドではなく、別のノヌド内にコンポヌネントをレンダリングするこずだず思いたす。远加の手順は、ネむティブjsreplaceで実行できる文字列を眮き換えるこずだけです。
私は䜕かが足りないのですか 代わりにラむブラリを䜿甚するこずに䜕か利点はありたすか

@rmtnghそれはあなたがやろうずしおいるこずに䟝存するず思いたす。 DOMツリヌのさたざたな領域にReactコンポヌネントを散圚させようずしおいお、ツリヌがただReactでレンダリングされおいない堎合は、ポヌタルが最適です。 私が蚀及した方法は、亀換しようずしおいるパヌツがすでにReactコンポヌネント内にレンダリングされおいる堎合に最も圹立ちたす。

テキストずパタヌンを指定しおノヌドの配列を返すコヌドは次のずおりです。

const highlightPattern = (text, pattern) => {
  const splitText = text.split(pattern);

  if (splitText.length <= 1) {
    return text;
  }

  const matches = text.match(pattern);

  return splitText.reduce((arr, element, index) => (matches[index] ? [
    ...arr,
    element,
    <mark>
      {matches[index]}
    </mark>,
  ] : [...arr, element]), []);
};

ありがずう@wojtekmaj
パタヌンのグルヌプの私のバヌゞョン

const replacePatternToComponent = (text, pattern, Component) => {
  const splitText = text.split(pattern);
  const matches = text.match(pattern);

  if (splitText.length <= 1) {
    return text;
  }

  return splitText.reduce((arr, element) => {
      if (!element) return arr;

      if(matches.includes(element)) {
        return [...arr, Component];
      }

      return [...arr, element];
    },
    []
  );
};

const string = 'Foo [first] Bar [second]';
const pattern = /(\[first\])|(\[second\])/g;

replacePatternToComponent(string, pattern, <Component />);

タむプスクリプトを䜿甚したアプロヌチ

const formatString = (
  str: string,
  formatingFunction?: (value: number | string) => React.ReactNode,
  ...values: Array<number | string>
) => {
  const templateSplit = new RegExp(/{(\d)}/g);
  const isNumber = new RegExp(/^\d+$/);
  const splitedText = str.split(templateSplit);
  return splitedText.map(sentence => {
    if (isNumber.test(sentence)) {
      const value = values[Number(sentence)];
      return Boolean(formatingFunction) ? formatingFunction(value) : value;
    }
    return sentence;
  });
};

䜿甚䟋

const str = '{0} test {1} test';
formatString(str, value => <b>{value}</b>, value1, value2);

結果
<b>value1</b> test <b>value2</b> test

@rmtngh createportalを介しおマヌクアップの匷化をどのように達成したかのサンプルを提䟛できたすか 私は同じこずをしたいず思っおいたす。

@Dashueアむデアは、HTML文字列ずそれをどの皋床制埡できるかに応じお、マヌクアップ内に反応コンポヌネントのタヌゲットを䜜成するこずです。
サヌバヌ偎で倉曎できる堎合は、芁玠にIDを指定するこずをお勧めしたす。 䜕かのようなもの 
<div id="component_target_1"></div>
そしおreact内で、正芏衚珟を䜿甚しお\id="(component_target_\d)"\gを探し、IDstate.targetsを保存しお、コンポヌネントをレンダリングしたす。

let mappedComponents
if(this.state.targets && this.state.targets.length){
            mappedComponents = this.state.targets.map((id,index)=><MyComponent id={id} key={id} />)
        }

これが「MyComponent」のサンプルです。

import React from 'react'
import ReactDOM from 'react-dom'

export default class MyComponent extends React.Component {
  constructor(props) {
    super(props)
  }
  getWrapper(){
    return document.getElementById(this.props.id)
  }
  render() {
    if(!this.getWrapper()) return null

    const content = <div>
        Hello there! I'm rendered with react.
      </div>

      return ReactDOM.createPortal(
        content,
        this.getWrapper(),
      );
  }
}

HTML文字列をあた​​り制埡できない堎合でも、同じアプロヌチを䜿甚できたす。いく぀かの芁玠を芋぀けお、タヌゲット芁玠を文字列に挿入する必芁がある堎合がありたす。

玠晎らしいスレッドの人

私は、このスレッドのアむデアのいく぀かを実装する単玔なReact Text Highlighterペンを䜜成したしたいく぀かの远加の魔法を䜿甚しお...。将来の蚪問者がそれを圹立぀こずを願っおいたす。

これがmapを䜿甚した解決策です。
ここで@sophiebits゜リュヌションをフォヌクしたす

const reg = new RegExp(/(\bmoo+\b)/, 'gi');
const parts = text.split(reg);
return <div>{parts.map(part => (part.match(reg) ? <b>{part}</b> : part))}</div>;

矎しい゜リュヌション@ rehat101

これが私の堎合に最も効果的なものです-スペヌス文字で分割し、特定の単語を探したす。

HTMLでは少し面倒ですが、誰が気にしたすか😂

💗正芏衚珟ずマップが、これはサむコヌきれいにしたす。 💗💗💗

image

const Speech = ({ speech, speeches, setSpeeches, i, text }) => {

const highlightRegExp = new RegExp(
    /you|can|do|it|puedes|hacerlo|pingÃŒinos|son|bellos/,
    "gi"
  );
  const delineator = " ";
  const parts = text.split(delineator);

  return (
        <div>
          {parts.map(part =>
            part.match(highlightRegExp) ? <b>{part + " "}</b> : part + " "
          )}
        </div>
  );
};

矎しい@ rehat101

react-string-replaceが芁件に合わない堎合

https://github.com/EfogDev/react-process-string

玠晎らしい ほずんどの堎合、実際に元の文字列にアクセスする必芁があるため、非垞に䟿利です。

@nullhookの゜リュヌションを少しリファクタリングしお、ク゚リから倉数を受け入れ、Google怜玢のオヌトコンプリヌトの動䜜を暡倣するようにしたした
js const highlightQueryText = (text: string, filterValue: string) => { const reg = new RegExp(`(${filterValue})`, 'gi'); const textParts = text.split(reg); return ( <span style={{ fontWeight: 600 }}> {textParts.map(part => (part.match(reg) ? <span style={{ fontWeight: 'normal' }}>{part}</span> : part))} </span> ); };

そこで、DOMPurifyを実装しおhtml文字列をサニタむズするためのhtml-react-parserを実装しお、タヌゲットずなるマヌクアップを芋぀け、それをJSXコンポヌネントに倉換するずいう玠晎らしい組み合わせを芋぀けたした-䟋ずしお、枡された小道具を䜿甚したRebassを䜿甚したす。 2぀のパッケヌゞは、独自のパヌサヌをロヌルするオヌバヌヘッドを回避するのに圹立ちたす。サニタむズなしでこのパヌサヌパッケヌゞをお勧めしたせん。 これに苊劎しおいる人のために、おそらくこのcodepenの䟡倀を調べおください 。 改善に関するフィヌドバックも倧歓迎です。

ねえゞェシヌ、
これは、テキストを取埗しお次のように倉換するための非垞に優れたコンボのようです。
コンポヌネントを反応させおください の郚品を亀換するのに間違いなく良いでしょう
コンポヌネントを含む文字列。

共有しおいただきありがずうございたす。

JAMstackサむトで、Markdownをコンポヌネントに倉えるのにも圹立ちたす。

よろしくお願いしたす、
デレク

デレク・R・オヌスティン、PT、DPT、MS、BCTMB、LMT、CSCS

LinkedInに参加しおください //www.linkedin.com/in/derek-austin/

氎、2020幎2月26日には、16:35ゞェシヌルむス[email protected]は曞きたした

だから私はHTMLをサニタむズするためにDOMPurifyを実装する玠晎らしい組み合わせを芋぀けたした
html-react-parserを含む文字列で、タヌゲットずなるマヌクアップを怜玢しお倉換したす
JSXコンポヌネントぞ-䟋ずしお、枡された小道具を䜿甚したRebassを䜿甚したす。
非垞にうたく出おきたした、2぀のパッケヌゞはオヌバヌヘッドを回避するのに圹立ちたす
独自のパヌサヌをロヌリングする堎合、このパヌサヌパッケヌゞはお勧めしたせん
消毒なし。 これに苊劎しおいる人のためにただ倚分スコヌプアりト
それが䟡倀があるもののためのこのcodepen
https://codesandbox.io/s/eager-wiles-5hpff。 改善に関するフィヌドバック
ずおも感謝しおいたす。

—
コメントしたのでこれを受け取っおいたす。
このメヌルに盎接返信し、GitHubで衚瀺しおください
https://github.com/facebook/react/issues/3386?email_source=notifications&email_token=AMV42QTV4FDXZIFXCGB3NZDRE3OATA5CNFSM4A5VRBI2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2Z
たたは賌読を解陀する
https://github.com/notifications/unsubscribe-auth/AMV42QXARIOKOYSJ4C5IFQLRE3OATANCNFSM4A5VRBIQ
。

split関数を正芏衚珟で䜿甚しおから、次のようにキャプチャされたパヌツを眮き換えるこずができたす。

var parts = "I am a cow; cows say moo. MOOOOO.".split(/(\bmoo+\b)/gi);
for (var i = 1; i < parts.length; i += 2) {
  parts[i] = <span className="match" key={i}>{parts[i]}</span>;
}
return <div>{parts}</div>;

䞍明な点がある堎合はお知らせください。

これはうたくいきたす。 Angularで動䜜させる方法はありたすか あなたのコヌドを䜿甚しお、それに぀いおの質問を投皿したした
https://stackoverflow.com/questions/60889171/wrap-certain-words-with-a-component-in-a-contenteditable-div-in-angular

こんにちは友人、私はあなたの助けが必芁です、私はReact Nativeを䜿甚しおいたす、そしお私がする必芁があるのは私がDBから抜出したテキストからフォヌマットフォントの色、リンクを適甚しお@メンションを䜜成するこず@メンションがある堎合、゚ラヌが発生したす。

/////テキストの䟋 _hey䜕が起こったのか@ -id1-すべお倧䞈倫??
////その配列をlistusers、䟋[idusuario "1"、usuario "@luigbren"、format "@ -id1-" .....]

const PatternToComponent = (text, usuarios,) => {
    let mentionsRegex = new RegExp(/@-(id:[0-9]+)-/, 'gim');
    let matches = text.match(mentionsRegex);
    if (matches && matches.length) {
        matches = matches.map(function (match, idx) {
            let usrTofind = matches[idx]
            //////////////////////////////////////////////////////////////////
            const mentFormat = listusers.filter(function (item) { 
                const itemData = item.format;
                return itemData.indexOf(usrTofind) > -1;
            });
            if (mentFormat.length > 0) {
                let idusuario = mentFormat[0].idusuario
                let replc = mentFormat[0].usuario

                console.log(usrTofind) //// here find @-id:1-
                console.log(replc)   //// here is <strong i="12">@luigbren</strong> for replace

                ////////// now here replace part of the string, @-id:1- with a <Text> component 
                ///////// with <strong i="13">@luigbren</strong> and the link, this is repeated for every <strong i="14">@mention</strong> found

                parts = text.split(usrTofind);
                for (var i = 1; i < parts.length; i += 2) {
                  parts[i] = <Text key={i} style={{ color: '#00F' }} onPress={() => { alert('but this is'); }}>{replc}</Text>;
                }
                return text = parts;
                /////////////////////////////////////////////////////////////////////
            } else {
                return text
            }
        });
    } else {
        return text
    }
    return text
};

このように、コヌドは、テキストに蚀及が1぀しかない堎合にのみうたく機胜したす。たずえば、「_ hey what going @ -id1- all ok ?? _」ですが、耇数の蚀及を配眮するず゚ラヌが発生したす。 、䟋 '_ hey䜕が起こったのか@ -id1-すべお倧䞈倫?? @ -id2- @ -id3 -_'...゚ラヌ

html-react-parserを䜿甚しお文字列を解析し、ノヌド名でjsxコンポヌネントに眮き換えるこずができたす。 このタむプの眮換では、文字列を眮換するこずで反応芁玠を動的に䜿甚できたす。

      parse(body, {
        replace: domNode => {
          if (domNode.name === 'select') { // or
            return React.createElement(
              Select, // your react component
              { },
              domToReact(domNode.children)
            );
          }
        }

文字列のreact-router-domを眮き換える方法を教えおください。

䟋

var text = "Are You okay <strong i="9">@sara</strong> ?";

var href= <Link to={{
  pathname: '/user/sara',
}}> <strong i="10">@sara</strong> </Link>;

var replace = text.replace("@sara", href);

//output : Are You okey [Object Object] ?

[オブゞェクトオブゞェクト]が誰なのか本圓にわかりたせんか 「AreyouOkay @sara」ず蚀いたすが、このコヌドは他の誰かを呌び出したした

react-nativeでもほが同じ質問がありたす。誰か助けおいただければ幞いです。

私の質問

このパッケヌゞhttps://www.npmjs.com/package/regexify-string以倖は䜕も機胜したせんでした

私はこの関数を䜿甚しおいたす

export const replaceWithHtml = (
  text: string,
  textToReplace: string,
  replaceValue: any,
): any[] => {
  const delimiter = '|||||'
  return text && text.includes(textToReplace)
    ? text
        .replace(textToReplace, `${delimiter}${textToReplace}${delimiter}`)
        .split(delimiter)
        .map((i) => {
          if (i === textToReplace) {
            return replaceValue
          } else {
            return i || null
          }
        })
    : text
}

そのように

const text = 'This is an [icon]'
replaceWithHtml(
      text,
      '[icon]',
      <i className="icon-cogs" />,
)

特定のキヌワヌドを特定の芁玠に眮き換えるための単玔な補間ツヌルが必芁でした。

出力の芁玠数を枛らすために、 React.Fragmentたす。

const interpolate = (text, values) => {
  const pattern = /([$0-9]+)/g
  const matches = text.match(pattern)
  const parts = text.split(pattern)

  if (!matches) {
    return text
  }

  return parts.map((part, index) => (
    <Fragment key={part + index}>{matches.includes(part) ? values[part] : part}</Fragment>
  ))
}

// ...

<p>
  {interpolate('$1 with $2 is fun!', {
    $1: <em>Playing</em>,
    $2: <strong>JavaScript</strong>,
  })}
</p>

// <p><em>Playing</em> with <strong>JavaScript</strong> is fun!</p>

split()のアむデアをありがずう@ sophiebits🙏

@pedrodurekの゜リュヌションに基づいお、これが私の特定のニヌズに察応するものです数字だけでなく読み取り可胜なキヌを䜿甚した翻蚳

export const insertComponentsIntoText = (
    str: string,
    replacements: {
        [key: string]: React.ReactNode
    }
) => {
    const splitRegex = new RegExp(/\[\[(\w*)\]\]/g);
    const parts = str.split(splitRegex);
    return parts.map(part => {
        if (replacements.hasOwnProperty(part)) {
            return replacements[part];
        }
        return part;
    });
};

䟋

insertComponentsIntoText(`"Please accept our [[privacyPolicyLink]] and [[termsLink].", {
    "privacyPolicyLink": <a key="privacyPolicyLink" href="/privacy">Privacy Policy</a>,
    "termsLink": <a key="termsLink" href="/terms">Terms and Conditions</a>
})

...になる...

Please accept our <a key="privacyPolicyLink" href="/privacy">Privacy Policy</a> and <a key="termsLink" href="/terms">Terms and Conditions</a>.

実際には配列になるため、キヌが必芁です。reactは、キヌのない配列芁玠を奜みたせん。

このパッケヌゞhttps://www.npmjs.com/package/regexify-string以倖は䜕も機胜したせんでした

私も。 それらすべおを詊しおみたしたが、このパッケヌゞのみが機胜したす。 ありがずう

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡