Является ли componentDidMount причиной исчезновения html.script?

avatar
Darren
8 апреля 2018 в 04:34
446
1
1

У меня возникают проблемы с подключением внешнего скрипта к компоненту моего приложения React/Gatsby. Приведенный ниже сценарий вызывается в компоненте, который используется в двух местах приложения.

Сначала это pages/index.js и загружается без проблем, но при вызове для использования на gatsby созданной странице (exports.createPages = ({ graphql, boundActionCreators }) => {) из шаблона сценарий загрузится, покажет содержимое и затем продолжит работу.

Вот код скрипта, монтируемого в компонент -

componentDidMount () {
    const tripadvisor = document.createElement("script");
    tripadvisorLeft.src = "https://www.jscache.com/wejs?wtype=selfserveprop&uniq=789&locationId=10467767&lang=en_NZ&rating=true&nreviews=0&writereviewlink=true&popIdx=true&iswide=true&border=false&display_version=2";
    tripadvisorLeft.async = true;
    document.body.appendChild(tripadvisor);
}

Я не получаю никаких ошибок из консоли.

ПРИМЕЧАНИЕ: В случае связи с ошибкой? У меня также есть этот код, использующий componentDidMount и componentWillUnmount в файле /layout/index.js, который обрабатывает body class для элементов navigation.

componentDidMount () {
  this.timeoutId = setTimeout(() => {
      this.setState({loading: ''});
  }, 100);
  this.innerContainer.addEventListener("scroll", this.handleHeaderStuck), 100;
  this.innerContainer.addEventListener("scroll", this.handleSubNavStuck), 200;
}

componentWillUnmount () {
  if (this.timeoutId) {
      clearTimeout(this.timeoutId);
  }
  this.innerContainer.removeEventListener("scroll", this.handleHeaderStuck);
  this.innerContainer.removeEventListener("scroll", this.handleSubNavStuck);
} 

ОБНОВЛЕНИЕ: Весь код

import React from 'react';
import Link from 'gatsby-link'
import styled from 'styled-components'

const Wrapper = styled.section`
  display:block;
`

class ReviewsPage extends React.Component {

    componentDidMount () {
        const tripadvisorLeft = document.createElement("script");
        tripadvisorLeft.src = "https://www.jscache.com/wejs?wtype=selfserveprop&uniq=789&locationId=10467767&lang=en_NZ&rating=true&nreviews=0&writereviewlink=true&popIdx=true&iswide=true&border=false&display_version=2";
        tripadvisorLeft.async = true;
        document.body.appendChild(tripadvisorLeft);
    }

    render() {           
        return (
            <Wrapper id="tripAdvisor">
                <div id="TA_selfserveprop789" className="TA_selfserveprop">
                    <ul id="3LacWzULQY9" className="TA_links 2JjshLk6wRNW">
                    <li id="odY7zRWG5" className="QzealNl"></li>
                    </ul>
                </div>
            </Wrapper>
        )
    }
}

export default ReviewsPage
Источник
Jason Spradlin
8 апреля 2018 в 06:36
0

Пожалуйста, покажите свой метод render()

Darren
8 апреля 2018 в 06:43
0

Спасибо @JasonSpradlin. Добавил код компонента. Дайте мне знать, если вам нужно больше.

Ответы (1)

avatar
Jason Spradlin
8 апреля 2018 в 06:53
1

Итак, все, что делает ваш componentDidMount(), это добавляет тег <script>, который ссылается на сторонний скрипт. Я предполагаю, что сторонний скрипт пытается добавить некоторую информацию или что-то в DOM (что-то, что вы можете увидеть визуально).

Однако DOM существует только между обновлениями компонентов. React будет полностью перерисовывать DOM (HTML внутри вашего компонента) каждый раз, когда обнаруживает изменение в State или Props. В данном случае я предполагаю, что Wrapper — это то, что сбрасывается каждый раз.

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

Было бы лучше, если бы у вас был сценарий, который асинхронно вызывает другую службу и получает данные, а затем позволяет React применить эти данные к DOM, вместо того, чтобы позволить сценарию редактировать саму DOM. Конечно, у вас, вероятно, нет контроля над тем, как на самом деле работает этот внешний скрипт, поэтому я говорю, что не знаю, как вам помочь.

Darren
8 апреля 2018 в 07:26
1

Это имеет большой смысл, Джейсон. Теперь, глядя на это, скрипты прерываются в тот момент, когда моя навигация добавляет класс. Что заставило меня понять, что я сделал опечатку в добавляемом классе. Сейчас поправили, скрипты загружаются нормально. Еще раз спасибо за помощь.

Darren
8 апреля 2018 в 07:29
1

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