質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Next.js

Next.jsは、Reactを用いたサーバサイドレンダリングなどを行う軽量なフレームワークです。Zeit社が開発しており、nextコマンドでプロジェクトを作成することにより、開発環境整備が整った環境が即時に作成できます。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

0回答

751閲覧

[Nextjs]"Expected server HTML to contain a matching <button> in <header>." が表示されてしまう

退会済みユーザー

退会済みユーザー

総合スコア0

Next.js

Next.jsは、Reactを用いたサーバサイドレンダリングなどを行う軽量なフレームワークです。Zeit社が開発しており、nextコマンドでプロジェクトを作成することにより、開発環境整備が整った環境が即時に作成できます。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2020/12/04 03:04

編集2020/12/04 03:13

聞きたいこと

webブラウザのウィンドウサイズによってヘッダーナビゲーションを動的に変更したいと思っています。

具体的にはモバイル用のウィンドウサイズとPC用のウィンドウサイズでヘッダーナビゲーションを変更しようと思っているのですが、
ウィンドウサイズをモバイル用サイズにした状態でブラウザをリロードすると、下のワーニングメッセージが表示されてしまいます。

react-dom.development.js?61bb:88 Warning: Expected server HTML to contain a matching <button> in <header>

ソースコード

  • _app.tsx

TypeScript

1import React from 'react'; 2import { AppProps } from 'next/app'; 3import { RecoilRoot } from 'recoil'; 4import '@@/styles/globals.css'; 5 6import HeaderContainer from '@/components/containers/HeaderContainer'; 7 8const App = ({ Component, pageProps }: AppProps): any => { 9 return ( 10 <RecoilRoot> 11 {/* ここでHeaderContainerを呼び出し */} 12 <HeaderContainer /> 13 <Component {...pageProps} /> 14 </RecoilRoot> 15 ); 16}; 17 18export default App; 19
  • HeaderContainer.tsx

TypeScript

1import * as React from 'react'; 2 3import Header from '@/components/gui/groups/Header'; 4import { useWindowDimensions } from '@/hooks'; 5 6const HeaderContainer: React.FC = () => { 7 const { width, height } = useWindowDimensions(); 8 // useWindowDimensions() カスタムコンポーネントから取得したwidth, heightをHeaderに引き渡し 9 return ( 10 <Header width={width} /> 11 ) 12} 13 14export default HeaderContainer; 15
  • useWindowDimensions.ts

TypeScript

1import * as React from 'react'; 2import { atom, useRecoilState } from 'recoil'; 3 4const getWindowDimensions = () => { 5 let width: number; 6 let height: number; 7 if (process.browser) { 8 width = window.innerWidth; 9 height = window.innerHeight; 10 } 11 return { 12 width, 13 height 14 }; 15} 16 17export const windowDimensionsState = atom({ 18 key: 'windowDimensionsState', 19 default: getWindowDimensions() 20}) 21 22const useWindowDimensions = () => { 23 const [windowDimensions, setWindowDimensions] = useRecoilState(windowDimensionsState); 24 React.useEffect(() => { 25 if (process.browser) { 26 const onResize = () => { 27 setWindowDimensions(getWindowDimensions); 28 } 29 window.addEventListener('resize', onResize); 30 return () => { 31 window.removeEventListener('resize', onResize) 32 } 33 } 34 }, []) 35 // stateで管理されたwidth, heightをreturnする 36 return windowDimensions; 37} 38 39export { useWindowDimensions } 40
  • Header.tsx

TypeScript

1import * as React from 'react'; 2import Link from 'next/link'; 3import styled from 'styled-components'; 4 5import { PRIMARY, TABLET_MEDIA, MOBILE_MEDIA } from '@/utils/constants'; 6import { Burger } from '@/components/gui/parts/Burger'; 7 8interface Props { 9 width: number 10} 11 12const Header: React.FC<Props> = (props) => { 13 const { width } = props; 14 15 if (width < 600) { 16 // モバイル用のHeader 17 return ( 18 <Wrapper> 19 <Burger /> 20 </Wrapper> 21 ) 22 } else { 23 // PC用のHeader 24 return ( 25 <Wrapper> 26 <Nav> 27 <Link href="/top"> 28 <StyledA>Top</StyledA> 29 </Link> 30 </Nav> 31 </Wrapper> 32 ); 33 } 34}; 35 36export default Header; 37 38const Wrapper = styled.header` 39 background-color: ${PRIMARY}; 40 position: fixed; 41 z-index: 999; 42 height: 55px; 43 top: 0; 44 left: 0; 45 right: 0; 46`; 47 48const Nav = styled.nav` 49 max-width: 800px; 50 box-sizing: border-box; 51 margin: 0 auto; 52 padding: 15px 5px; 53 ${TABLET_MEDIA} { 54 padding: 15px 30px; 55 } 56 ${MOBILE_MEDIA} { 57 padding: 15px; 58 } 59`; 60 61const StyledA = styled.a` 62 color: rgba(255, 255, 255, 0.8); 63 transition: color 0.15s ease; 64 line-height: 24px; 65 display: inline-block; 66 vertical-align: middle; 67 font-weight: 300; 68 letter-spacing: 0.075em; 69 margin-right: 1.8em; 70 cursor: pointer; 71 &:hover { 72 color: #fff; 73 } 74`; 75
  • Burger.tsx

TypeScript

1import * as React from 'react'; 2import styled from 'styled-components'; 3 4const Burger = () => { 5 return ( 6 <Button> 7 <div /> 8 <div /> 9 <div /> 10 </Button> 11 ) 12} 13 14export { Burger }; 15 16const Button = styled.button` 17 position: absolute; 18 top: 5%; 19 left: 2rem; 20 display: flex; 21 flex-direction: column; 22 justify-content: space-around; 23 width: 2rem; 24 height: 2rem; 25 background: transparent; 26 border: none; 27 cursor: pointer; 28 padding: 0; 29 z-index: 10; 30 31 &:focus { 32 outline: none; 33 } 34 35 div { 36 width: 2rem; 37 height: 0.25rem; 38 border-radius: 10px; 39 transition: all 0.3s linear; 40 position: relative; 41 transform-origin: 1px; 42 } 43`; 44

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問