2019.7.17
LPなんか作るときにこういったSNSボタンを埋め込むことがあります。ただReactのサイトで埋め込もうと思ったらReactのライフサイクル上でscriptの読み込みなどを発生させる必要があるので、少し面倒なところがあります。
LINEの友だち追加ボタンの埋め込みコードは↓ここから取得できます。
今回はこのボタンを埋め込みます。
埋め込みコードはこんな感じ。scriptタグがあるので、div
要素がちゃんとマウントされた状態でscirptを読み込む必要があります。
<div class="line-it-button" data-lang="ja" data-type="friend" data-lineid="@lineteamjp" style="display: none;"></div>
<script src="https://d.line-scdn.net/r/web/social-plugin/js/thirdparty/loader.min.js" async="async" defer="defer"></script>
React HelmetはReactでhead
タグが記述できるライブラリです。
GitHub - nfl/react-helmet: A document head manager for React
<Helmet>
<script src="https://d.line-scdn.net/r/web/social-plugin/js/thirdparty/loader.min.js" />
</Helmet>
これだとdiv
要素のマウント後に読み込まれるかどうかが担保されないかもしれないのでまずそうです。
結局、useEffect
を使った方法でscriptを読み込ませることにしました。wrapper
はボタンを囲う親要素のrefです。
useEffect
の第二引数を[]
にするとComponentDidMount
相当の挙動になるのでdiv
要素のマウントが担保されます。
const wrapper = useRef(null);
useEffect(() => {
const script = document.createElement("script");
script.src =
"https://d.line-scdn.net/r/web/social-plugin/js/thirdparty/loader.min.js";
script.async = true;
script.defer = true;
(wrapper.current as any).appendChild(script);
}, []);
これだと他のページで同じコンポーネントを使っている場合、ページ遷移したときにscript内の関数が呼ばれないのでボタンが正しく表示できません。
結局、scriptのコードを読んで呼び出している関数を呼ぶという泥臭い感じで実装しました。
const wrapper = useRef(null);
useEffect(() => {
const win = window as any;
if (win.LineIt) {
win.LineIt.loadButton();
} else {
const script = document.createElement("script");
script.src =
"https://d.line-scdn.net/r/web/social-plugin/js/thirdparty/loader.min.js";
script.async = true;
script.defer = true;
(wrapper.current as any).appendChild(script);
}
}, []);