
今現在、ラーメン屋のサイトを作ろうとReactを勉強していて、海外のyoutubeを見ながらサイトを作っています。
そこで、サイトを模写している中で、Buttonコンポーネントを特定の条件下でのみナビゲーションバー表示させる方法が複雑だったので、紹介したいと思います。
今回の内容
・Buttonコンポーネントの作成
・Buttonコンポーネントの表示
今回はこんな感じでやっていきたいと思います。
今回の内容
Buttonコンポーネントの作成
まずは特定の条件の時にCSSを更新するためのButtonコンポーネントを作成します。
import React from 'react'
import './Button.css';
import { Link } from 'react-router-dom';
const STYLES = ['btn--primary', 'btn--outline'];
const SIZES = ['btn--medium', 'btn--large'];
export const Button = ({
children,
type,
onClick,
buttonStyle,
buttonSize
}) => {
return (
<Link to='/sign-up' className='btn-mobile'>
<button
className={`btn ${checkButtonStyle} ${checkButtonSize}`}
onClick={onClick}
type={type}>
{children}
</button>
</Link>
);
};
export default Button;
まずは、上から理解していきます。
const STYLES = ['btn--primary', 'btn--outline'];
const SIZES = ['btn--medium', 'btn--large'];
こちらでは、STYLES
とSIZES
の配列を作成しておきます。こちらはあとで使います。
配列については下記を参照。
export const Button
では、関数コンポーネントでButtonを定義します。関数コンポーネントは下記を参照しました。
引数に({ children, type, onClick, buttonStyle, buttonSize })
を入れます。
const checkButtonStyle = STYLES.includes(buttonStyle)
? buttonStyle : STYLES[0];
const checkButtonSize = SIZES.includes(buttonSize)
? buttonSize : SIZES[0];
以上のコードの説明をします。よく理解できていないので、詳しくは説明できていないかもしれないです。
const checkButtonStyle
では変数を定義していきます。
先ほど定義したSTYLES
の中で、buttonStyle
が含まれている場合は、buttonStyle
をそのまま実行し、buttonStyle
が含まれていない場合は、STYLES
の最初の部分を実行する、という式です。
つまり、buttonStyle
がなければデフォルトで'btn--primary'
が渡されるということですね。
<Button
className='btns'
buttonStyle='btn--primary'
buttonSize='btn--large'>
WATCH <i className='far fa-play-circle' />
</Button>
上記ではbuttonStyle
とbuttonSize
が渡されているので、指定されたクラスのCSSが表示されます。
もしbuttonSize
とbuttonStyle
が渡されなければ、デフォルトでbtn--primary
とbtn--medium
が適用されます。
上記のボタンでは、WATCH
がprimary
で左のMENU
がoutline
が適用されています。
このようにbuttonStyle
とbuttonSize
を定義してあげることで、条件によってクラスCSS分けることができます。
それでは処理の方を見ていきます。
return (
<Link to='/menu' className='btn-mobile'>
<button
className={`btn ${checkButtonStyle} ${checkButtonSize}`}
onClick={onClick}
type={type}>
{children}
</button>
</Link>
これでlinkタグを使い、クリックしたときのリンク先とクラス名を定義しています。
そしてそのあとは、onClick
とtype
をそれぞれ引数を代入します。他のファイルでonClick
とtype
が渡されれば、Button
の引数に渡されて実行されるというイメージですかね。多分そんな感じです。
そして{ children }
では、下記のように引数が渡されます。
<Button>ここに入るのが{children}に渡される</Button>
これでButtonコンポーネントの作成は完了です。
それでは、どのようにして表示させていくのかを見ていきます。
Buttonコンポーネントの表示
import React,{useState, useEffect} from 'react'
import { Link } from 'react-router-dom';
import './Navbar.css';
import { Button } from './Button';
function Navbar() {
const [click, setClick] = useState(false);
const [button, setButton] = useState(true);
const handleClick = () => setClick(!click);
const closeMobileMenu = () => setClick(false);
const showButton = () =>{
if(window.innerWidth <= 960){
setButton(false)
}else{
setButton(true);
}
};
useEffect(() => {
showButton();
}, []);
window.addEventListener('resize', showButton);
return (
<>
<nav className="navbar">
<div className="navbar-container">
<Link to="/" className="navbar-logo" onClick={closeMobileMenu}>
ISSEI <i className="fab fa-typo3" />
</Link>
<div className="menu-icon" onClick={handleClick}>
<i className={click ? 'fas fa-times' : 'fas fa-bars'} />
</div>
<ul className={click ? 'nav-menu active': 'nav-menu'}>
//省略
</ul>
{button && <Button buttonStyle='btn--outline'>SIGN UP</Button>}
</div>
</nav>
</>
);
}
export default Navbar;
上のコードはナビゲーションバーのコードです。
このコードだと下記のように表示されます。

それではコードについて理解していきます。
注目するのは以下のコードです。
const [button, setButton] = useState(true); //state変数buttonを定義
//画面の大きさによってbuttonを表示・非表示にする
const showButton = () =>{
if(window.innerWidth <= 960){
setButton(false)
}else{
setButton(true);
}
};
//showButton変数をレンダーごとに呼び出す
useEffect(() => {
showButton();
}, []);
//サイズが変更するイベントがあるごとにshowButtonを実行させる
window.addEventListener('resize', showButton);
//state変数のボタンbuttonがtrueの時にButtonコンポーネントが呼び出されるようになる
{button && <Button buttonStyle='btn--outline'>SIGN UP</Button>}
まずはstate変数を定義します。
showButton
変数で、画面の大きさが変化するとsetButton
が変更し、button
の値が変化します。
ステートフックについての理解は下記を参照。
useEffect
に関しては前回やってので、省きます。
window.addEventListener('resize', showButton);では、windowの大きさが変化するとshowButton
を実行するようになります。
{button && <Button buttonStyle='btn--outline'>SIGN UP</Button>}では、button
がtrueの時のみにButtonコンポーネントがレンダリングされるようになります。
そしてbuttonStyle
しか指定していないので、buttonSize
はデフォルトのmedium
が適用されます。
&&
は条件付きレンダー というものです。下記を参考にしました。
流れを見ると、画面の大きさが変わるとaddEventListener
が実行されてshowButton
が実行されます。
setButton
がtrue
に慣ればbutton
がtrue
になり、Buttonコンポーネントがレンダリングされるという流れです。
まとめ
Buttonコンポーネントのレンダーが少し複雑だったので、今回紹介しました。
自分がきちんと理解できていないことをアウトプットすると頭が整理されます。
これでも完全に理解できたわけではないですが、それなりに理解はできたと思います。
この調子で次回もやっていきたいと思います。
最後まで読んでいただきありがとうございました。