본문 바로가기
학원에서 배운 것/React

KDT 5th 웹개발자 입문 수업 38일차

by 쿠리의일상 2023. 3. 29.

리액트 prettier, eslint 로 초기 세팅하기

1. npm i -D prettier 

2. npm i -D eslint

 

리액트 폴더 최상위에 세팅하기

1. .vscode 폴더 생성

2. .vscode 폴더 안에 settings.json 파일 생성

{
  "[javascript]": {
    "editor.maxTokenizationLineLength": 2500,
    "editor.formatOnSave": true,
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[javascriptreact]": {
  	"editor.maxTokenizationLineLength" : 2500,
    "editor.formatOnSave" : true,
    "editor.defaultFormatter" : "esbenp.prettier-vscode"
  }
}

3. .prettierrc 파일을 폴더 최상위에 세팅

{
  "semi" : true,
  "singleQuote" : true,
  "trailingComma": "all"
}

4. npx eslint --init 으로 설정 시작! -> 설정 끝에  .eslintrc.js 파일이 생김

설정해주기

to check syntax and find problems

-> javascript modules

-> react

-> no

-> browser

-> javascript

-> yes

-> npm

 

module.exports = {
  env: {
    browser: true,
    es2021: true,
  },
  extends: ['eslint:recommended', 'plugin:react/recommended'],
  overrides: [],
  parserOptions: {
    ecmaVersion: 'latest',
    sourceType: 'module',
  },
  plugins: ['react'],
  rules: {
    'react/prop-types': 'off',
  },
};

 

 

useRef

리액트에서 DOM 요소에 접근하고자 할 때나 리렌더링이 되더라도 참조값이 유지되어야 하는 값이 있을 때 사용하는 훅 함수

 

useRef 함수는 current 속성을 가지고 있는 객체를 반환하는데 인자로 넘어간 초기값을 기본적으로 current 속성에 할당한다.

current 속성은 값을 변경해도 리렌더링이 되지 않는다는 특징이 있다.

 

컴포넌트가 리렌더링 되어도 값을 유지하고 싶을 때 state는 컴포넌트 리렌더링이 되어버린다.

변수는 리렌더링할 때마다 변수값은 초기화 된다.

이럴 때 쓰는 것이 useRef 이다.

인풋 필드에서 무언가를 입력 받는 상황일 때 useState 를 사용하면 인풋 태그 자체가 계속 리렌더링 되어서 문제가 생길텐데 이런 경우 사용해준다.

 

useRef 를 사용하면 참조하고자 하는 DOM 요소에 ref 속성을 주고 해당 태그의 변화를 감지하거나 DOM 요소를 컨트롤 할 수 있다. 보통 컴포넌트에 존재하는 인풋 태그의 값을 받거나 JS에서 DOM 요소를 관리하는 역할을 수행한다.

 

1. useRef 사용 선언해주기

import { useState, useRef } from 'react';

2. useRef() 를 사용하여 변수 선언해주기

  const inputField = useRef();

3. DOM 요소에 접근할 태그에 ref 속성을 넣어주기

<input
    name="h2"
    value={text}
    placeholder="입력"
    ref={inputField}
    onChange={onChangeText2}
/>

4. 변화가 있을 때마다 해당 ref 변수의 current에 접근해주기 -> current 를 안써주면 변경 불가함

  // useRef 활용
  const onChangeText2 = () => {
    setText(inputField.current.value);
  };

useRef 변수를 콘솔에 찍는다면,
입력 받은 값은 current.value 로 접근이 가능한 것이다. 그밖에도 current 로 className 이나, style 등에 접근이 가능하다!

즉, ref변수로는 useRef 클래스에만 접근한 것이며, 해당 DOM에 접근하려면 current 를 써줘야 하는 것이다.

 

 

useRef 로 포커스 이동 시키기

export default function ChangeFocus() {
  const input1 = useRef();
  const input2 = useRef();

  const changeFocus1 = () => {
    input1.current.focus();
  };

  const changeFocus2 = () => {
    input2.current.focus();
  };

  return (
    <div>
      <input type="text" ref={input1} />
      <input type="text" ref={input2} />
      <br />
      <br />
      <button onClick={changeFocus1}>1번 인풋으로</button>
      <button onClick={changeFocus2}>2번 인풋으로</button>
    </div>
  );
}

 

useRef 로 DOM 요소에 접근해서 색 바꿔주기

import { useRef } from 'react';

export default function ColorInput() {
  const colorPalet = useRef();
  const divEl = useRef();

  const ChangeDivBGColor = () => {
    divEl.current.style.backgroundColor = colorPalet.current.value;
  };

  return (
    <div ref={divEl}>
      <input type="text" ref={colorPalet} />
      <br />
      <button onClick={ChangeDivBGColor}>색 적용</button>
    </div>
  );
}

 

useRef 의 다른 용법으로는 current 에 특정 값을 저장해두고 state 가 변경되어도 값이 변하지 않아야 하는 경우이다.

카운트 업의 시작과 일시 중지 같은 것에 활용할 수 있다.

 

숫자 맞추기 실습

import { useRef, useState } from 'react';

export default function QuizNumber() {
  const [state, setState] = useState(true);
  const correctInput = useRef();

  const operation1 = parseInt(Math.random() * 10);
  const operation2 = parseInt(Math.random() * 10);
  let operatorArr = ['+', '-', 'x'];
  let operator = parseInt(Math.random() * operatorArr.length);
  let result = 0;

  operator = operatorArr[operator];
  switch (operator) {
    case '+':
      result = operation1 + operation2;
      break;
    case '-':
      result = operation1 - operation2;
      break;
    case 'x':
      result = operation1 * operation2;
      break;
    default:
      break;
  }

  const submitButton = () => {
    if (parseInt(correctInput.current.value) === result) {
      alert('정답입니다!');
      setState(!state);
    } else {
      alert('오답입니다!');
      correctInput.current.focus();
    }
    correctInput.current.value = '';
  };

  return (
    <div>
      <h2>
        {operation1} {operator} {operation2}
      </h2>
      <br />
      <input ref={correctInput} type="text" />
      <button onClick={submitButton}>정답 제출</button>
    </div>
  );
}

 

 

useState / useRef / Variable 비교

state ref variable
변경 되면 리렌더링! 변경 되어도 리렌더링X 변경 되면 재선언으로 초기화 됨!
  ►리렌더링 되더라도 동일한 참조값을 유지할 때 사용해준다.  

 

 

React.Fragment

return 값의 최상위 태그 역할을 하는 <div></div> 를 빼면 에러가 발생한다.

이는 리액트의 특성상 부모 요소가 필요하기 때문이다.

 

그러나 실제 리액트에서 컴포넌트를 조합할 때, 최상위에 div를 사용하지 않고 반환해야하는 경우가 생기는데, 그럴 때 사용하는 것이 바로 <React.Fragment> 이다.

다만, react 라이브러리 기능이므로 react 를 import 해줘야 한다.

import React from 'react';

export default function ReactFragment() {
  return (
    <React.Fragment>
      <h2>안녕하세요</h2>
      <h2>반갑습니다</h2>
    </React.Fragment>
  );
}

하지만 <React.Fragment> 는 길기 때문에 <> 로 대체가 가능하다! (import 해줄 필요도 없다)

export default function ReactFragment() {
  return (
    <>
      <h2>안녕하세요</h2>
      <h2>반갑습니다</h2>
    </>
  );
}

 

React.Fragment 가 필요할 때는?

display : flex 같은 속성이 지정된 컴포넌트에 자식 컴포넌트를 넣어줄 때, div 등이 추가되면 디자인이 깨질 위험이 크다.

그럴 땐 <></> 나 <React.Fragment> 를 사용해주면 된다!

 

흔하지 않은 경우지만, 테이블 요소에 테이블 내용을 컴포넌트로 삽입하는 경우... 테이블 요소 안에는 div 태그가 들어가지 못하므로 해당 경우도 React.Fragment 를 사용해준다.

 

그래서 return 으로 html 을 넘겨줄 때 해당 기능을 사용하도록 해준다.