Как я могу игнорировать ошибки TypeScript при добавлении тегов скрипта через реагирующий шлем?

Следующий код TSX генерирует ошибки TypeScript. //@ts-ignore не работает

<Helmet>
  <script>
    (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
    new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
    j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
    'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
    })(window,document,'script','dataLayer','GTM-*******');
  </script>
</Helmet>

Следующий код работает, но я хотел бы использовать ребенка <script> тег против script свойство компонента.

<Helmet
  script={[
    {
      type: 'application/javascript',
      innerHTML: '(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({\'gtm.start\':new Date().getTime(),event:\'gtm.js\'});var f=d.getElementsByTagName(s)[0],j=d.createElement(s),dl=l!=\'dataLayer\'?\'&l=\'+l:\'\';j.async=true;j.src=\'https://www.googletagmanager.com/gtm.js?id=\'+i+dl;f.parentNode.insertBefore(j,f);})(window,document,\'script\',\'dataLayer\',\'GTM-*******\');'
    }
  ]}
/>

1 ответ

Разобрался благодаря https://github.com/nfl/react-helmet/issues/334.

<Helmet>
  <script>
    {`
      alert('BOOM');
    `} 
  </script>
</Helmet>

Этот сценарий должен быть встроен как часть вашей кучи компонентов?

Я столкнулся с аналогичной проблемой при использовании API iframe YouTube, и было решено создать элемент script и ссылаться на объекты javascript, созданные после того, как они существуют (если вам нужно сделать это, похоже, что вы буквально просто хотите импортировать JS). Мне не нужно было создавать компонент реакции для этого, если не было визуальных элементов, которыми я хотел бы управлять.

// GoogleTagManager.ts

export class GoogleTagManager {
  someVariable: someVariableType = null 

  constructor () {
    const script: HTMLScriptElement = <HTMLScriptElement>document.createElement('script')

    script.src = '[URL_TO_JS_FILE]'

    script.onload = (): void => console.log('loaded google tag manager')

    document.body.appendChild(script)
  }

  WaitForVariable (): void {
    let timeout: number

    const OnTimeout = (): void => {
      if (timeout) {
        clearTimeout(timeout)
      }

      if (typeof [TARGET_VARIABLE] !== 'undefined') {
        this.someVariable = [TARGET_VARIABLE]
        return
      }

      timeout = setTimeout(OnTimeout, 1000)
    }
  }
}

Если вы хотите отобразить некоторую информацию, вы можете превратить ее в React Component и переместить логику конструктора в componentDidMount. В качестве альтернативы я хотел бы рассмотреть отправку любых результирующих данных в хранилище и иметь отдельный компонент для рендеринга результирующих данных.

С осторожностью вы можете использовать dangerousSetInnerHTML так:


<script
  dangerouslySetInnerHTML={{
    __html: `
    (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
    new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
    j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
    'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
    })(window,document,'script','dataLayer','GTM-*******');
`,
  }}
/>

Но будьте осторожны с атаками через межсайтовый скриптинг (XSS).

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