인라인 스크립팅을 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 패키지가 있습니다 .
최신 정보:
이제 고리가 useEffect
생겼으므로 다음과 같이 사용하는 것이 더 좋습니다 .
useEffect(() => {
const script = document.createElement('script');
script.src = "https://use.typekit.net/foobar.js";
script.async = true;
document.body.appendChild(script);
return () => {
document.body.removeChild(script);
}
}, []);
다음은 커스텀 훅 (예 :)에 대한 훌륭한 후보입니다 hooks/useScript.js
.
import { useEffect } from 'react';
const useScript = url => {
useEffect(() => {
const script = document.createElement('script');
script.src = url;
script.async = true;
document.body.appendChild(script);
return () => {
document.body.removeChild(script);
}
}, [url]);
};
export default useScript;
다음과 같이 사용할 수 있습니다.
import useScript from 'hooks/useScript';
const MyComponent = props => {
useScript('https://use.typekit.net/foobar.js');
// rest of your component
}
답변
위의 답변 외에도 다음을 수행 할 수 있습니다.
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>
);
}
};
답변
<script>
SSR (서버 측 렌더링)에서 차단 이 필요한 경우 에는 접근 방식 componentDidMount
이 작동하지 않습니다.
react-safe
대신 라이브러리를 사용할 수 있습니다 . React의 코드는 다음과 같습니다.
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>
답변
Alex Mcmillan이 제공 한 답변 은 가장 도움이되었지만 더 복잡한 스크립트 태그에는 효과가 없었습니다.
나는 이미 “src”를 설정 한 다양한 기능을 가진 긴 태그에 대한 해결책을 제시하기 위해 그의 대답을 약간 조정했습니다.
(사용 사례의 경우 스크립트가 여기에 반영되어 머리 속에 살 필요가있었습니다) :
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);
}
답변
이 특정 사례에 대한 React 구성 요소를 만들었습니다 : https://github.com/coreyleelarson/react-typekit
Typekit Kit ID를 소품으로 전달하면됩니다.
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;
답변
를 사용하는 매우 좋은 해결 방법이 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));
}
이것은 임의의 HTML에서 작동하며 같은 컨텍스트 정보를 유지합니다 document.currentScript
.