1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

reactを使って横幅サイズ次第で別のHTMLを出す

Last updated at Posted at 2019-12-08

#なぜやるのか
とあるプロジェクトで、結構厳密なデザインHTMLをBootstrapのレスポンシブで対応を試みた所、かなり期待通りの動きをしないので、Bootstrapを捨ててReactで画面サイズによって見せるHTMLをそもそも変えようと思った。

#用意したもの
react(本体)
react-responsive (MediaQuery関係)
react-snap (react プリレンダリング)
ソースはこちら
https://github.com/UG/reactResponsiveTest

##PCサイトの見栄え (例)
pc1.png

##スマホサイトの見栄え(例)
sm1.png

#実際のコード
###App.js

import React from 'react';
import './App.css';
import pcsite from './pcsite.jsx'
import smartphone from './smartphon.jsx'

function App() {
  const [size, setSize] = React.useState({ 'width': window.innerWidth, 'height': window.innerHeight });
  window.addEventListener('resize', function () {
    setSize({ 'width': window.innerWidth, 'height': window.innerHeight });
  }, true);
  return (
    <div>
      {size.width > 375 * 2 ? pcsite() : smartphone()}
    </div>
  );
}

export default App;

制御としてはwindow.innerWidthをリサイズ毎にステートセットし直す。 スマホは横幅375*2扱いが多いみたいなので、一旦そこをボーダーにしてみた。

###pcsite.jsx

import React from 'react';

export default function pcsite() {
    const test = 'hoge';
    const html = `
    <br>
    <br>
    <br>
    <div class="center">
        <div class="yellowBackground">
            <div class="stepBox">
                <span class="circleStep">1</span>
                <p>test text</p>
            </div>
            <div class="stepBox">
                <span class="circleStep">2</span>
                <p>test text</p>
            </div>
            <div class="stepBox">
                <span class="circleStep">3</span>
                <p>${test}</p>
            </div>
        </div>
    </div>
    `;
    return (
        <div dangerouslySetInnerHTML={{ __html: html }} />
    );
}

reactのdomはHTMLぽいけど、HTMLじゃないので、この様にtemplate stringを使ってHTMLを挿入し、普通のDOMに突っ込むとタグごと出てくるので dangerouslySetInnerHTMLで出力しないとだめらしい。
物々しい名前なのは実際にx-site Scriptingの脆弱性があるから基本使うなという事らしい。
(const使ってれば大丈夫な気がするが、そういう事ではないのか?)

テンプレート文字列にも変数は打ち込めるので、サーバーサイドのテンプレート言語と遜色ないと思う。
スマホHTMLは割愛、ほぼpcsiteと同じ内容で、向いてるCSSが違うとか、全く違うHTMLを書いて構わない。

#ハマった点、まだハマり中

  • react-responsiveを使うと、期待した通りの動きができると思ったけど初回しか識別しない模様。
  • PCのブラウザを、DevToolでスマホに変えれば、スマホの方が出てくれる
  • でもブラウザの方をいくら縮めても、スマホという認識をしない。おそらくuser-agentとか色々見てるせい
  • テンプレート文字列にBootstrapを使うと、bootstrap.min.cssをlinkタグで利用すると、CSSがぶっ壊れて描画しなくなるので、共存できないかもしれない。
  • react-bootstrapなるものが存在するが、htmlで div class="sm"とかできない<sm>というタグを使うことになるので、HTML-bootstrapで作った物をreact-bootstrapでそのまま使う事はできない気がする。
  • prerender部分まだエラーが出てちゃんとできてないのでいつかやる。SEO上ゴミだとクライアントが許してくれないと思うので。

そのうち追記するかもです。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?