React / JSX에 스크립트 태그 추가
인라인 스크립팅을 React 구성 요소에 추가하려고하는 비교적 간단한 문제가 있습니다. 내가 지금까지 무엇을 :
'use strict';
import '../../styles/pages/people.scss';
import React, { Component } from 'react';
import DocumentTitle from 'react-document-title';
import { prefix } from '../../core/util';
export default class extends Component {
render() {
return (
<DocumentTitle title="People">
<article className={[prefix('people'), prefix('people', 'index')].join(' ')}>
<h1 className="tk-brandon-grotesque">People</h1>
<script src="https://use.typekit.net/foobar.js"></script>
<script dangerouslySetInnerHTML={{__html: 'try{Typekit.load({ async: true });}catch(e){}'}}></script>
</article>
</DocumentTitle>
);
}
};
나는 또한 시도했다 :
<script src="https://use.typekit.net/foobar.js"></script>
<script>try{Typekit.load({ async: true });}catch(e){}</script>
두 방법 모두 원하는 스크립트를 실행하지 않는 것 같습니다. 나는 그것이 누락 된 간단한 것 같아요. 아무도 도와 줄 수 있습니까?
추신 : foobar를 무시하고 실제로 공유하고 싶지 않은 실제 ID가 있습니다.
이 컴포넌트가 렌더링 될 때마다 또는이 컴포넌트가 DOM에 마운트 될 때마다 스크립트를 반복해서 가져오고 실행 하시겠습니까?
아마도 다음과 같이 시도하십시오.
componentDidMount () {
const script = document.createElement("script");
script.src = "https://use.typekit.net/foobar.js";
script.async = true;
document.body.appendChild(script);
}
그러나 이것은로드하려는 스크립트를 모듈 / 패키지로 사용할 수없는 경우에만 유용합니다. 먼저, 나는 항상 :
- npm 에서 패키지를 찾으십시오.
- 내 프로젝트에서 패키지를 다운로드하여 설치하십시오 (
npm install typekit
). import
내가 필요한 패키지 (import Typekit from 'typekit';
)
이것은 패키지 react
와 react-document-title
예제 를 설치 한 방법 일 가능성이 있으며 npm에서 사용 가능한 Typekit 패키지가 있습니다 .
위의 답변 외에도 다음을 수행 할 수 있습니다.
import React from 'react';
export default class Test extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
const s = document.createElement('script');
s.type = 'text/javascript';
s.async = true;
s.innerHTML = "document.write('This is output by document.write()!')";
this.instance.appendChild(s);
}
render() {
return <div ref={el => (this.instance = el)} />;
}
}
div가 바인딩되고 this
스크립트가 삽입됩니다.
데모는 codesandbox.io 에서 찾을 수 있습니다
가장 좋아하는 방법은 React Helmet을 사용하는 것입니다. 이미 사용했던 방식으로 문서 헤드를 쉽게 조작 할 수있는 구성 요소입니다.
예 :
import React from "react";
import {Helmet} from "react-helmet";
class Application extends React.Component {
render () {
return (
<div className="application">
<Helmet>
<script src="https://use.typekit.net/foobar.js"></script>
<script>try{Typekit.load({ async: true });}catch(e){}</script>
</Helmet>
...
</div>
);
}
};
https://github.com/nfl/react-helmet
Alex Mcmillan이 제공 한 답변 은 가장 도움이되었지만 더 복잡한 스크립트 태그에는 효과가 없었습니다.
I slightly tweaked his answer to come up with a solution for a long tag with various functions that was additionally already setting "src".
(For my use case the script needed to live in head which is reflected here as well):
componentWillMount () {
const script = document.createElement("script");
const scriptText = document.createTextNode("complex script with functions i.e. everything that would go inside the script tags");
script.appendChild(scriptText);
document.head.appendChild(script);
}
If you need to have <script>
block in SSR (server-side rendering), an approach with componentDidMount
will not work.
You can use react-safe
library instead. The code in React will be:
import Safe from "react-safe"
// in render
<Safe.script src="https://use.typekit.net/foobar.js"></Safe.script>
<Safe.script>{
`try{Typekit.load({ async: true });}catch(e){}`
}
</Safe.script>
I created a React component for this specific case: https://github.com/coreyleelarson/react-typekit
Just need to pass in your Typekit Kit ID as a prop and you're good to go.
import React from 'react';
import Typekit from 'react-typekit';
const HtmlLayout = () => (
<html>
<body>
<h1>My Example React Component</h1>
<Typekit kitId="abc123" />
</body>
</html>
);
export default HtmlLayout;
There is a very nice workaround using Range.createContextualFragment
.
/**
* Like React's dangerouslySetInnerHTML, but also with JS evaluation.
* Usage:
* <div ref={setDangerousHtml.bind(null, html)}/>
*/
function setDangerousHtml(html, el) {
if(el === null) return;
const range = document.createRange();
range.selectNodeContents(el);
range.deleteContents();
el.appendChild(range.createContextualFragment(html));
}
This works for arbitrary HTML and also retains context information such as document.currentScript
.
You can use npm postscribe
to load script in react component
postscribe('#mydiv', '<script src="https://use.typekit.net/foobar.js"></script>')
for multiple scripts, use this
var loadScript = function(src) {
var tag = document.createElement('script');
tag.async = false;
tag.src = src;
document.getElementsByTagName('body').appendChild(tag);
}
loadScript('//cdnjs.com/some/library.js')
loadScript('//cdnjs.com/some/other/library.js')
Tried all of the proposed solutions but none work. I am trying to embed this to a component but it's not loading. this is a banner from bannersnack.com.
<script type="text/javascript">
var bannersnack_embed = {"hash":"bxpien9pr","width":1190,"height":300,"t":1559889975,"userId":39254375,"responsive":true,"type":"html5"};
</script>
<script type="text/javascript" src="//cdn.bannersnack.com/iframe/embed.js"></script>
componentDidMount() {
const head = document.querySelector("head");
const script = document.createElement("script");
script.setAttribute(
"src",
"https://assets.calendly.com/assets/external/widget.js"
);
head.appendChild(script);
}
You can find best answer at the following link:
const loadDynamicScript = (callback) => { const existingScript = document.getElementById('scriptId'); if (!existingScript) { const script = document.createElement('script'); script.src = 'url'; // URL for the third-party library being loaded. script.id = 'libraryName'; // e.g., googleMaps or stripe document.body.appendChild(script); script.onload = () => { if (callback) callback(); }; } if (existingScript && callback) callback(); };
Solution depends on scenario. Like in my case, I had to load a calendly embed inside a react component.
Calendly looks for a div and reads from it's data-url
attribute and loads an iframe inside the said div.
It is all good when you first load the page: first, div with data-url
is rendered. Then calendly script is added to body. Browser downloads and evaluates it and we all go home happy.
Problem comes when you navigate away and then come back into the page. This time the script is still in body and browser doesn't re-download & re-evaluate it.
Fix:
- On
componentWillUnmount
find and remove the script element. Then on re mount, repeat the above steps. - Enter
$.getScript
. It is a nifty jquery helper that takes a script URI and a success callback. Once the script it loaded, it evaluates it and fires your success callback. All I have to do is in mycomponentDidMount
$.getScript(url)
. Myrender
method already has the calendly div. And it works smooth.
참고URL : https://stackoverflow.com/questions/34424845/adding-script-tag-to-react-jsx
'Programming' 카테고리의 다른 글
익명의 재귀 PHP 함수 (0) | 2020.05.14 |
---|---|
CSS 센터 디스플레이 인라인 블록? (0) | 2020.05.14 |
Git에 의해 커밋되지 않은 변경 사항을 Master에서 새 지점으로 변경 (0) | 2020.05.14 |
Excel에서 행을 변경하여 다른 변수를 일정하게 유지하는 방법 (0) | 2020.05.14 |
IE에서 배경 크기 작업을하려면 어떻게해야합니까? (0) | 2020.05.14 |