如何在React中创建并插入字符串中间的元素?

huangapple go评论71阅读模式
英文:

How to create and insert element in the middle of string in react?

问题

以下是代码部分的翻译:

import React, { useState, useEffect } from "react";
import "./styles.css";
import { posts } from "./data";

let slicedOne = posts.slice(0, 5);
let slicedTwo = posts.slice(5, 10);
let slicedThree = posts.slice(10);

export default function App() {
  const [feeds, setFeeds] = useState([]);
  const [currentView, setCurrentView] = useState(0);
  const [slicedFeeds, setSlicedFeeds] = useState([
    slicedOne,
    slicedTwo,
    slicedThree
  ]);
  const [texts, setTexts] = useState(
    slicedFeeds[currentView].map((feed) => feed.fullText)
  );

  let arr = [];
  const handleOnChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    let copiedTexts = texts;
    for (let text of copiedTexts) {
      for (let i = 0; i < text.length; i++) {
        console.log(text[i]);
        if (text[i].toLowerCase() === e.target.value) {
          console.log("matched");
          let span = document.createElement("span"); // this is not working...
          span.style.color = "red";
          span.append(text[i]);
        }
      }
    }
  };

  return (
    <div>
      <div>
        <input type="text" onChange={handleOnChange} />
      </div>
      {slicedFeeds[currentView].map((feed, idx) => {
        return (
          <div key={feed.dateTimeCreated}>
            {feed.from.name} {feed.dateTimeLastModified}
            <div>{feed.fullText}</div>
            <br></br>
          </div>
        );
      })}
      <div>
        <button onClick={() => setCurrentView(0)}>1</button>
        <button onClick={() => setCurrentView(1)}>2</button>
        <button onClick={() => setCurrentView(2)}>3</button>
      </div>
    </div>
  );
}

如果你需要代码的中文翻译,请提供具体需要翻译的部分。

英文:

As user types in input field, I want the matching letter in the text to be highlighted in red. So texts displayed is "Hello" and user types in "h" then I would like text to be updated to &lt;span style=&quot;color:red&quot;&gt;H&lt;/span&gt;ello. I'm trying it with vanilla js way, which is createElement span then add style to it then append a letter, but no luck. What is the react way of accomplishing this? https://codesandbox.io/s/msft-machine-coding-react-ts-to9szx?file=/src/App.tsx:0-1613

App.tsx

import React, { useState, useEffect } from &quot;react&quot;;
import &quot;./styles.css&quot;;
import { posts } from &quot;./data&quot;;
let slicedOne = posts.slice(0, 5);
let slicedTwo = posts.slice(5, 10);
let slicedThree = posts.slice(10);
export default function App() {
const [feeds, setFeeds] = useState([]);
const [currentView, setCurrentView] = useState(0);
const [slicedFeeds, setSlicedFeeds] = useState([
slicedOne,
slicedTwo,
slicedThree
]);
const [texts, setTexts] = useState(
slicedFeeds[currentView].map((feed) =&gt; feed.fullText)
);
let arr = [];
const handleOnChange = (e: React.ChangeEvent&lt;HTMLInputElement&gt;) =&gt; {
let copiedTexts = texts;
for (let text of copiedTexts) {
for (let i = 0; i &lt; text.length; i++) {
console.log(text[i]);
if (text[i].toLowerCase() === e.target.value) {
console.log(&quot;matched&quot;);
let span = document.createElement(&quot;span&quot;); // this is not working...
span.style.color = &quot;red&quot;;
span.append(text[i]);
}
}
}
};
return (
&lt;div&gt;
&lt;div&gt;
&lt;input type=&quot;text&quot; onChange={handleOnChange} /&gt;
&lt;/div&gt;
{slicedFeeds[currentView].map((feed, idx) =&gt; {
return (
&lt;div key={feed.dateTimeCreated}&gt;
{feed.from.name} {feed.dateTimeLastModified}
&lt;div&gt;{feed.fullText}&lt;/div&gt;
&lt;br&gt;&lt;/br&gt;
&lt;/div&gt;
);
})}
&lt;div&gt;
&lt;button onClick={() =&gt; setCurrentView(0)}&gt;1&lt;/button&gt;
&lt;button onClick={() =&gt; setCurrentView(1)}&gt;2&lt;/button&gt;
&lt;button onClick={() =&gt; setCurrentView(2)}&gt;3&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
);
}

data.tsx

export const posts = [
{
fullText:
&quot;Hello this is just some random post created to show an example mock    post for this coding challenge&quot;,
dateTimeCreated: &quot;2020-07-20T18:44:11Z&quot;,
dateTimeLastModified: &quot;2020-07-20T18:44:11Z&quot;,
type: &quot;Post&quot;,
from: {
name: &quot;Garima&quot;,
email: &quot;garima@gmail.com&quot;
}
},
{
fullText:
&quot;Hello this is just some random post created to show an example mock post for this coding challenge. this needs to be completed in two hours.Hello this is just some random post created to show an example mock post for this coding challenge. this needs to be completed in two hoursHello this is just some random post created to show an example mock post for this coding challenge. this needs to be completed in two hoursHello this is just some random post created to show an example mock post for this coding challenge. this needs to be completed in two hoursHello this is just some random post created to show an example mock post for this coding challenge. this needs to be completed in two hoursHello this is just some random post created to show an example mock post for this coding challenge. this needs to be completed in two hoursHello this is just some random post created to show an example mock post for this coding challenge. this needs to be completed in two hoursHello this is just some random post created to show an example mock post for this coding challenge. this needs to be completed in two hoursHello this is just some random post created to show an example mock post for this coding challenge. this needs to be completed in two hoursHello this is just some random post created to show an example mock post for this coding challenge. this needs to be completed in two hoursHello this is just some random post created to show an example mock post for this coding challenge. this needs to be completed in two hours&quot;,
dateTimeCreated: &quot;2020-07-20T18:44:11Z&quot;,
dateTimeLastModified: &quot;2020-07-20T18:44:11Z&quot;,
type: &quot;Reply&quot;,
from: {
name: &quot;Viniket&quot;,
email: &quot;garima@gmail.com&quot;
}
},
{
fullText:
&quot;Hello this is just some random post created to show an example mock    post for this coding challenge&quot;,
dateTimeCreated: &quot;2020-07-20T18:44:11Z&quot;,
dateTimeLastModified: &quot;2020-07-20T18:44:11Z&quot;,
type: &quot;Reply&quot;,
from: {
name: &quot;Bhushan&quot;,
email: &quot;garima@gmail.com&quot;
}
},
{
fullText:
&quot;Hello this is just some random post created to show an example mock    post for this coding challenge&quot;,
dateTimeCreated: &quot;2020-07-20T18:44:11Z&quot;,
dateTimeLastModified: &quot;2020-07-20T18:44:11Z&quot;,
type: &quot;Post&quot;,
from: {
name: &quot;Tanvi&quot;,
email: &quot;garima@gmail.com&quot;
}
},
{
fullText:
&quot;Hello this is just some random post created to show an example mock    post for this coding challenge&quot;,
dateTimeCreated: &quot;2020-07-20T18:44:11Z&quot;,
dateTimeLastModified: &quot;2020-07-20T18:44:11Z&quot;,
type: &quot;Post&quot;,
from: {
name: &quot;Rahul&quot;,
email: &quot;garima@gmail.com&quot;
}
},
{
fullText:
&quot;Hello this is just some random post created to show an example mock    post for this coding challenge&quot;,
dateTimeCreated: &quot;2020-07-20T18:44:11Z&quot;,
dateTimeLastModified: &quot;2020-07-20T18:44:11Z&quot;,
type: &quot;Post&quot;,
from: {
name: &quot;Deeksha&quot;,
email: &quot;garima@gmail.com&quot;
}
},
{
fullText:
&quot;Hello this is just some random post created to show an example mock    post for this coding challenge&quot;,
dateTimeCreated: &quot;2020-07-20T18:44:11Z&quot;,
dateTimeLastModified: &quot;2020-07-20T18:44:11Z&quot;,
type: &quot;Post&quot;,
from: {
name: &quot;Swati&quot;,
email: &quot;garima@gmail.com&quot;
}
},
{
fullText:
&quot;Hello this is just some random post created to show an example mock    post for this coding challenge&quot;,
dateTimeCreated: &quot;2020-07-20T18:44:11Z&quot;,
dateTimeLastModified: &quot;2020-07-20T18:44:11Z&quot;,
type: &quot;Post&quot;,
from: {
name: &quot;Ketki&quot;,
email: &quot;garima@gmail.com&quot;
}
},
{
fullText:
&quot;Hello this is just some random post created to show an example mock    post for this coding challenge&quot;,
dateTimeCreated: &quot;2020-07-20T18:44:11Z&quot;,
dateTimeLastModified: &quot;2020-07-20T18:44:11Z&quot;,
type: &quot;Post&quot;,
from: {
name: &quot;Preksha&quot;,
email: &quot;garima@gmail.com&quot;
}
},
{
fullText:
&quot;Hello this is just some random post created to show an example mock    post for this coding challenge&quot;,
dateTimeCreated: &quot;2020-07-20T18:44:11Z&quot;,
dateTimeLastModified: &quot;2020-07-20T18:44:11Z&quot;,
type: &quot;Post&quot;,
from: {
name: &quot;Sonali&quot;,
email: &quot;garima@gmail.com&quot;
}
},
{
fullText:
&quot;Hello this is just some random post created to show an example mock    post for this coding challenge&quot;,
dateTimeCreated: &quot;2020-07-20T18:44:11Z&quot;,
dateTimeLastModified: &quot;2020-07-20T18:44:11Z&quot;,
type: &quot;Post&quot;,
from: {
name: &quot;Gagan&quot;,
email: &quot;garima@gmail.com&quot;
}
},
{
fullText:
&quot;Hello this is just some random post created to show an example mock    post for this coding challenge&quot;,
dateTimeCreated: &quot;2020-07-20T18:44:11Z&quot;,
dateTimeLastModified: &quot;2020-07-20T18:44:11Z&quot;,
type: &quot;Post&quot;,
from: {
name: &quot;Pratiksha&quot;,
email: &quot;garima@gmail.com&quot;
}
},
{
fullText:
&quot;Hello this is just some random post created to show an example mock    post for this coding challenge&quot;,
dateTimeCreated: &quot;2020-07-20T18:44:11Z&quot;,
dateTimeLastModified: &quot;2020-07-20T18:44:11Z&quot;,
type: &quot;Reply&quot;,
from: {
name: &quot;Bhagyashree&quot;,
email: &quot;garima@gmail.com&quot;
}
},
{
fullText:
&quot;Hello this is just some random post created to show an example mock    post for this coding challenge&quot;,
dateTimeCreated: &quot;2020-07-20T18:44:11Z&quot;,
dateTimeLastModified: &quot;2020-07-20T18:44:11Z&quot;,
type: &quot;Post&quot;,
from: {
name: &quot;Milind&quot;,
email: &quot;garima@gmail.com&quot;
}
}
];

答案1

得分: 2

以下是您要求的翻译部分:

// Helper function to add highlighted markup to selected text
// based on the input keyword:
const highlighted = (keyword, text) =>
  // We sanitize the produced text to avoid XSS attacks
  // before passing the data to the dangerouslySetInnerHTML prop
  DOMPurify.sanitize(
    text.replace(
      new RegExp(`(${keyword})`, "gi"),
      "<span style='background:orange;'>$1</span>"
    )
  );

export default function App() {
  const [keyword, setKeyword] = useState(null);
  // 1) Watch for input from the search box and update the state
  // The state change will trigger a re-render of the Component
  const handleOnChange = (e) => {
    setKeyword(e.target.value);
  };

  return (
    <>
      <input type="text" onChange={handleOnChange} />
      {posts.map((feed) => (
        <div key={feed.dateTimeCreated}>
          {feed.from.name} {feed.dateTimeLastModified}
          <p dangerouslySetInnerHTML={{ __html: highlighted(keyword, feed.fullText) }} />
        {/* The keyword is updated, there's a re-render and the feed text is filtered through the highlighter helper function to produce the highlighted markup */}
        </div>
      ))}
    </>
  );
}

Working demo:

<!-- begin snippet: js hide: true console: true babel: true -->

<!-- language: lang-js -->

const posts = [
  {
    fullText:
      "Hello this is just some random post created to show an example mock    post for this coding challenge",
    dateTimeCreated: "2020-07-20T18:44:11Z",
    dateTimeLastModified: "2020-07-20T18:44:11Z",
    type: "Post",
    from: {
      name: "Garima",
      email: "garima@gmail.com"
    }
  }
];

const highlighted = (keyword, text) =>
  DOMPurify.sanitize(
    text.replace(
      new RegExp(`(${keyword})`, "gi"),
      "<span style='background:orange;'>$1</span>"
    )
  );

function App() {
  const [keyword, setKeyword] = React.useState(null);
  const handleOnChange = (e) => {
    setKeyword(e.target.value);
  };
  return (
    <React.Fragment>
      <input type="text" onChange={handleOnChange} />
      {posts.map((feed) => (
        <div key={feed.dateTimeCreated}>
          {feed.from.name} {feed.dateTimeLastModified}
          <p dangerouslySetInnerHTML={{ __html: highlighted(keyword, feed.fullText) }} />
        </div>
      ))}
    </React.Fragment>
  );
}

ReactDOM.render(<App/>, document.getElementById("root"));

<!-- language: lang-html -->

<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://cdnjs.cloudflare.com/ajax/libs/dompurify/2.4.3/purify.min.js" crossorigin></script>
<div id="root"></div>

<!-- end snippet -->

希望这对您有所帮助。如果您需要任何其他翻译,请告诉我。

英文:

The link that shanmukha vangaru suggested is a great place to start, but here is some working code to experiment with and study.

It uses the dangerouslySetInnerHTML prop but properly sanitises the input using DOMPurify, in order to be safe.

import { useState } from &quot;react&quot;;
import DOMPurify from &quot;dompurify&quot;;
const posts = [
  {
    fullText:
      &quot;Hello this is just some random post created to show an example mock    post for this coding challenge&quot;,
    dateTimeCreated: &quot;2020-07-20T18:44:11Z&quot;,
    dateTimeLastModified: &quot;2020-07-20T18:44:11Z&quot;,
    type: &quot;Post&quot;,
    from: {
      name: &quot;Garima&quot;,
      email: &quot;garima@gmail.com&quot;
    }
  }
];

// Helper function to add highlighted markup to selected text
// based on the input keyword:
const highlighted = (keyword, text) =&gt;
  // We sanitize the produced text to avoid XSS attacks
  // before passing the data to the dangerouslySetInnerHTML prop
  DOMPurify.sanitize(
    text.replace(
      new RegExp(`(${keyword})`, &quot;gi&quot;),
      &quot;&lt;span style=&#39;background:orange;&#39;&gt;$1&lt;/span&gt;&quot;
    )
);

export default function App() {
  const [keyword, setKeyword] = useState(null);
  // 1) Watch for input from the search box and update the state
  // The state change will trigger a re-render of the Component
  const handleOnChange = (e) =&gt; {
    setKeyword(e.target.value);
  };

  return (
    &lt;&gt;
      &lt;input type=&quot;text&quot; onChange={handleOnChange} /&gt;
      {posts.map((feed) =&gt; (
        &lt;div key={feed.dateTimeCreated}&gt;
          {feed.from.name} {feed.dateTimeLastModified}
          &lt;p dangerouslySetInnerHTML={{ __html: highlighted(keyword, feed.fullText) }} /&gt;
        {/* The keyword is updated, there&#39;s a re-render and the feed text is filtered through the highlighter helper function to produce the highlighted markup */}
        &lt;/div&gt;
      ))}
    &lt;/&gt;
  );
}

Working demo:

<!-- begin snippet: js hide: true console: true babel: true -->

<!-- language: lang-js -->

const posts = [
{
fullText:
&quot;Hello this is just some random post created to show an example mock    post for this coding challenge&quot;,
dateTimeCreated: &quot;2020-07-20T18:44:11Z&quot;,
dateTimeLastModified: &quot;2020-07-20T18:44:11Z&quot;,
type: &quot;Post&quot;,
from: {
name: &quot;Garima&quot;,
email: &quot;garima@gmail.com&quot;
}
}
];
const highlighted = (keyword, text) =&gt;
DOMPurify.sanitize(
text.replace(
new RegExp(`(${keyword})`, &quot;gi&quot;),
&quot;&lt;span style=&#39;background:orange;&#39;&gt;$1&lt;/span&gt;&quot;
)
);
function App() {
const [keyword, setKeyword] = React.useState(null);
const handleOnChange = (e) =&gt; {
setKeyword(e.target.value);
};
return (
&lt;React.Fragment&gt;
&lt;input type=&quot;text&quot; onChange={handleOnChange} /&gt;
{posts.map((feed) =&gt; (
&lt;div key={feed.dateTimeCreated}&gt;
{feed.from.name} {feed.dateTimeLastModified}
&lt;p dangerouslySetInnerHTML={{ __html: highlighted(keyword, feed.fullText) }} /&gt;
&lt;/div&gt;
))}
&lt;/React.Fragment&gt;
);
}
ReactDOM.render(&lt;App/&gt;, document.getElementById(&quot;root&quot;));

<!-- language: lang-html -->

&lt;script src=&quot;https://unpkg.com/react@17/umd/react.development.js&quot; crossorigin&gt;&lt;/script&gt;
&lt;script src=&quot;https://unpkg.com/react-dom@17/umd/react-dom.development.js&quot; crossorigin&gt;&lt;/script&gt;
&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/dompurify/2.4.3/purify.min.js&quot; crossorigin&gt;&lt;/script&gt;
&lt;div id=&quot;root&quot;&gt;&lt;/div&gt;

<!-- end snippet -->

As always, there are many ways to solve a problem in software development, so make sure to study the other proposed solutions in the link provided in the comments. Each solution, has always pros and cons and must be balanced according to the requirements and trade offs.

答案2

得分: 1

以下是您要翻译的代码部分:

import React, { useState } from "react";

const App = () => {
  const [searchTerm, setSearchTerm] = useState("");
  const [text, setText] = useState("Lorem Ipsum is simply dummy text");

  const highlightText = (text, searchTerm) => {
    const regex = new RegExp(`(${searchTerm})`, "gi");
    const parts = text.split(regex);
    const highlighted = [];

    for (let i = 0; i < parts.length; i++) {
      const part = parts[i];
      if (regex.test(part)) {
        highlighted.push(<mark key={i}>{part}</mark>);
      } else {
        highlighted.push(part);
      }
    }

    return highlighted;
  };

  return (
    <div>
      <input
        type="text"
        value={searchTerm}
        onChange={(e) => setSearchTerm(e.target.value)}
      />
      <p>{highlightText(text, searchTerm)}</p>
    </div>
  );
};

export default App;
英文:

Can you check this solution

import React, { useState } from &quot;react&quot;;
const App = () =&gt; {
const [searchTerm, setSearchTerm] = useState(&quot;&quot;);
const [text, setText] = useState(&quot;Lorem Ipsum is simply dummy text&quot;);
const highlightText = (text, searchTerm) =&gt; {
const regex = new RegExp(`(${searchTerm})`, &quot;gi&quot;);
const parts = text.split(regex);
const highlighted = [];
for (let i = 0; i &lt; parts.length; i++) {
const part = parts[i];
if (regex.test(part)) {
highlighted.push(&lt;mark key={i}&gt;{part}&lt;/mark&gt;);
} else {
highlighted.push(part);
}
}
return highlighted;
};
return (
&lt;div&gt;
&lt;input
type=&quot;text&quot;
value={searchTerm}
onChange={(e) =&gt; setSearchTerm(e.target.value)}
/&gt;
&lt;p&gt;{highlightText(text, searchTerm)}&lt;/p&gt;
&lt;/div&gt;
);
};
export default App;

huangapple
  • 本文由 发表于 2023年2月6日 04:19:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/75355254.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定