Как сделать HTML-элементы из строки, а затем выбрать элемент в React?

Я хочу получить веб-сайт, а затем преобразовать его в HTML, но не помещать весь HTML в React DOM, сначала выбрать элемент (и, очевидно, его дочерние элементы), а затем поместить этот конкретный элемент в React DOM. Я хочу примерно следующее:

convertHtml = () => {
  fetch(url)
  .then(res => res.text())
  .then(htmlString => {
    /*for example the htmlString looks like this:
      "<html>
        <body>
          <div>
            <p id = "elementWhatIWant">
              I want to earn this element (not the text inside)
            </p>
          </div>
        </body>
      </html>"
    */
    //what I want:
    return stringToHtml(htmlString).getElementById("elementWhatIWant")
  })
}
render = () => <div className = "App">
  {this.convertHtml()}
</div>

Я провел небольшое исследование, но, как я увидел, есть только один способ получить элемент в React, и это ссылка. Поскольку это строка, мы не можем напрямую указать ссылку ни на один элемент. Я подумал, что мы можем проанализировать строку и

  • найдите элемент elementWhatIWant и поместите ссылку на него в виде строки или
  • найдите элемент elementWhatIWant, найдите его закрывающий тег и верните только эту часть строки

Ни один из них не кажется хорошим подходом, поэтому я спрашиваю: как лучше всего зарабатывать то, что я хочу?

Возможно, вам понадобится это, но имейте в виду, что это может сказаться на безопасности. Не принимайте dangerouslySetInnerHTML как должное.

ugh StackExchange 27.10.2018 14:40

Ну, у вас также есть ReactDom.findDOMNode, поэтому, если вы объедините предложение FrankerZ с этим ... и извлечете код yuor в отдельный компонент, вы можете сделать это без особых хлопот.

Goran.it 27.10.2018 14:45

Да, я читал об этом, но я хочу выбрать только дочерний элемент из строки и вставить только его для рендеринга.

Gergő Horváth 27.10.2018 14:45

В этом случае создайте в памяти пустой элемент DIV. Заполните его строкой innerHTML, и вы сможете получить дочерние узлы с помощью querySelector.

Goran.it 27.10.2018 14:46

Можете ли вы предоставить мне пример кода использования этих методов?

Gergő Horváth 27.10.2018 14:49

Вот пример (похожая проблема): stackoverflow.com/questions/49869953/…

Goran.it 27.10.2018 14:53
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
6
1 424
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Как упоминалось ранее, если это простые элементы HTML, вам следует рассмотреть возможность использования реагировать-html-парсер. Это решит вашу проблему гораздо более безопасным способом, чем приведенный ниже dangerouslySetInnerHTML. Смотрите мои коды и ящик здесь для получения дополнительной информации:

class App extends React.Component {
  constructor() {
    super();
    this.state = {
      html: null
    };

    this.fetchHtml = this.fetchHtml.bind(this);
  }

  async fetchHtml() {
    const html = await ajaxPlaceholder();
    console.info("Got new html!", html);

    const parsed = $(html).find("span");

    // From https://stackoverflow.com/a/5744268/4875631
    this.setState({
      html: parsed[0].outerHTML
    });
  }

  render() {
    return (
      <div className = "App">
        <h1>Hello CodeSandbox</h1>
        Escaped: <div>{this.state.html}</div>
        <br />
        Not Dangerous: <div>{parser(this.state.html)}</div>
        <button onClick = {this.fetchHtml}>Fetch some Html</button>
      </div>
    );
  }
}

Я создал кодовый ящик здесь, который демонстрирует функциональность dangerouslySetInnerHTML. Как уже упоминалось, вы хотите использовать dangerouslySetInnerHTML = {{ __html: HTML_YOU_WANT_TO_SET }} для установки html. Пожалуйста, используйте это с осторожностью:

dangerouslySetInnerHTML is React’s replacement for using innerHTML in the browser DOM. In general, setting HTML from code is risky because it’s easy to inadvertently expose your users to a cross-site scripting (XSS) attack. So, you can set HTML directly from React, but you have to type out dangerouslySetInnerHTML and pass an object with a __html key, to remind yourself that it’s dangerous.

const ajaxPlaceholder = () => {
  return new Promise(resolve => {
    setTimeout(() => resolve("<h1>Test Return</h1>"), 500);
  });
};

class App extends React.Component {
  constructor() {
    super();
    this.state = {
      html: null
    };

    this.fetchHtml = this.fetchHtml.bind(this);
  }

  async fetchHtml() {
    const html = await ajaxPlaceholder();
    console.info("Got new html!", html);

    this.setState({
      html
    });
  }

  render() {
    return (
      <div className = "App">
        <h1>Hello CodeSandbox</h1>
        Escaped: <div>{this.state.html}</div>
        <br />
        Dangerous: <div dangerouslySetInnerHTML = {{ __html: this.state.html }} />
        <button onClick = {this.fetchHtml}>Fetch some Html</button>
      </div>
    );
  }
}

Что, если h1 имеет обертку div в качестве ответа на выборку, но мы хотим выбрать только h1?

Gergő Horváth 27.10.2018 14:54

@ GergőHorváth Подумайте о том, чтобы проверить мой обновленный ответ (я привел пример с использованием response-html-parser, который намного безопаснее)

ugh StackExchange 27.10.2018 15:10

Другие вопросы по теме