리액트 Responsive nav bar 구현

노요셉·2019년 11월 20일
0

TIL

목록 보기
23/23

소스 코드 : https://github.com/leaveittogod0123/ReactLab/tree/master/ResponsiveNavBar

create-react-app을 사용하셔도 되고 또는
웹팩을 통해서 프로젝트 설정을 다 하신 상황을 가정합니다.

웹팩을 통해 프로젝트 설정
eslint, prettier설정

css를 수정하는데 바로바로 적용이 안되요. css도 hot loader가 있을것 같은데..

있습니다. 구글링하자마자 나옵니다. css-hot-loader

설치방법
package.json이 위치한 디렉토리에서요.

yarn add -D css-hot-loader

webpack.config.js도 수정합니다.

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
  entry: ["./src/index"],
  resolve: {
    extensions: [".jsx", ".js", ".scss"]
  },
  output: {
    path: path.join(__dirname, "/dist"),
    filename: "index_bundle.js"
  },
  module: {
    rules: [
      {
        test: /\.jsx?/,
        ...
      },
      {
        test: /\.scss$/,
        exclude: /node_module/,
        use: [
          "css-hot-loader", <- 추가해줍니다.
          MiniCssExtractPlugin.loader,
          {
            loader: "css-loader",
            options: {
              modules: {
                localIdentName: "[path][name]__[local]"
              }
            }
          },
          "sass-loader"
        ]
      }
    ]
  },
  plugins: [
    ...
  ]
};

레퍼런스: css-hot-loader

the css module with sass 에서 media query 사용하기

현재 반응형 네이게이션 바를 구현 중인데요.
media query를 통해 반응형 레이아웃을 구현할 수 있습니다.


$small: 768px;
@media screen and (max-width: $small){
	style...
}

React에서 Element.classList를 사용하고 싶어요.

classList.toggle을 사용하고 싶어서,
React Ref를 사용해서 구현했습니다. 맞는 방법인지는 모르겠지만,
정상적으로 동작하니 일단은 넘아가고, 모두 구현한 후에 다시 살펴봐야겠습니다.

import React, { Component } from "react";
import styles from "../sass/Nav.module.scss";

export default class Nav extends Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }

  burgerOnClick = () => {
    this.myRef.current.classList.toggle(styles.navActive);
  };

  render() {
    return (
      <nav className={styles.nav}>
        <div className={styles.logo}>
          <h4>The Nav</h4>
        </div>
        <ul className={styles.navLinks} ref={this.myRef}>
          <li>
            <a href="#">Home</a>
          </li>
          <li>
            <a href="">About</a>
          </li>
          <li>
            <a href="">Work</a>
          </li>
          <li>
            <a href="">Projects</a>
          </li>
        </ul>
        <div
          className={styles.burger}
          onClick={this.burgerOnClick}
          onKeyDown={this.burgerOnClick}
        >
          <div className="line1" />
          <div className="line2" />
          <div className="line3" />
        </div>
      </nav>
    );
  }
}

레퍼런스 How to get a React Component reference to change its class using classList?

레퍼런스 : Ref와 DOM - reacjs

후기

css module + sass로 css를 세세하게 건드리는게 너무나도 귀찮은 부분이 많네요. 다음에는 styled component를 사용해보려고 합니다.


에러

eslint 에러.. airbnb를 사용하는데 커스터마이징을 많이 하게 되네요.

.eslintrc나 저 같은 경우에는 package.json에 "eslintCofig" 프로퍼티에 넣어서 사용합니다. rules에 import/no-extraneous-dependencies라는 eslint 에러표시를 꺼버립니다.

"eslintConfig": {
    "parser": "babel-eslint",
    "extends": [
      "airbnb",
      "prettier"
    ],
    "rules": {
      "react/prefer-stateless-function": 0,
      "react/jsx-filename-extension": 0,
      "react/jsx-one-expression-per-line": 0,
      "react/destructuring-assignment": 0,
      "react/no-array-index-key": 0,
      "jsx-a11y/no-static-element-interactions": 0,
      "import/no-extraneous-dependencies": [
        "error",
        {
          "peerDependencies": true
        }
      ]
    },
    "env": {
      "browser": true,
      "node": true
    }
  }

레퍼런스: import/no-extraneous-dependencies: Forbid the use of extraneous packages


오류내용을 그대로 검색하여 찾아보니, @babel/plugin-proposal-class-properties를 설치한 후, 웹팩 설정을 바꿔주니 해결이 되었습니다.

@babel/plugin-proposal-class-properties를 설치해줍니다.

yarn add -D @babel/plugin-proposal-class-properties

webpack.config.js를 수정합니다.

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
  entry: ["./src/index"],
  resolve: {
    extensions: [".jsx", ".js", ".scss"]
  },
  output: {
	...
  },
  module: {
    rules: [
      {
        test: /\.jsx?/,
        exclude: /node_module/,
        use: {
          loader: "babel-loader",
          options: {
            presets: ["@babel/preset-env", "@babel/preset-react"],
            plugins: ["@babel/plugin-proposal-class-properties"] <- 추가해줍니다.
          }
        }
      },
      {
        test: /\.scss$/,
        ...
      }
    ]
  },
  plugins: [
	...
  ]
};

레퍼런스: Support for the experimental syntax 'classProperties' isn't currently enabled

profile
서로 아는 것들을 공유해요~

0개의 댓글