PROGRAMMING

Buttonコンポーネントを特定の条件でのみ表示する【React.js】

今現在、ラーメン屋のサイトを作ろうと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'];

こちらでは、STYLESSIZESの配列を作成しておきます。こちらはあとで使います。

配列については下記を参照。

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>

上記ではbuttonStylebuttonSizeが渡されているので、指定されたクラスのCSSが表示されます。

もしbuttonSizebuttonStyleが渡されなければ、デフォルトでbtn--primarybtn--mediumが適用されます。

上記のボタンでは、WATCHprimaryで左のMENUoutlineが適用されています。

このようにbuttonStylebuttonSizeを定義してあげることで、条件によってクラスCSS分けることができます。

それでは処理の方を見ていきます。

return (
  <Link to='/menu' className='btn-mobile'>
    <button
    className={`btn ${checkButtonStyle} ${checkButtonSize}`}
      onClick={onClick}
      type={type}>
      {children}
    </button>
  </Link>

これでlinkタグを使い、クリックしたときのリンク先とクラス名を定義しています。

そしてそのあとは、onClicktypeをそれぞれ引数を代入します。他のファイルでonClicktypeが渡されれば、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が実行されます。

setButtontrueに慣ればbuttontrueになり、Buttonコンポーネントがレンダリングされるという流れです。

まとめ

Buttonコンポーネントのレンダーが少し複雑だったので、今回紹介しました。

自分がきちんと理解できていないことをアウトプットすると頭が整理されます。

これでも完全に理解できたわけではないですが、それなりに理解はできたと思います。

この調子で次回もやっていきたいと思います。

最後まで読んでいただきありがとうございました。

-PROGRAMMING

Copyright © Iseblog ,@2020 All Rights Reserved.