SCSS

  • CSS를 편하게 쓸 수 있도록 도와줌
  • node-sass 설치하기
yarn add node-sass@4.14.1 open-color sass-loader classnames
  • 중첩된 속성
div {
	p {
		color: #888888;
		font: {
			family: sans-serif;
			size: 14px;
		}
	}

	img {
		width: 400px;
	}
}
  • 상위 요소 이어쓰기 (& 사용)
div {
	background-color: green
	&:hover { background-color: blue }
}

.div {
	background-color: green
	&_blue { background-color: blue }
}
  • 변수 사용
$defaultSize: 20px;
$className: blue;

p {
	font-size: #{$defaultSize};
	&.#{$className} {color: #{$className}}
}

styled-components

  • 컴포넌트에 스타일을 직접 입히는 방식
  • styled-components 패키지 설치하기
yarn add styled-components
  • class 이름 지을 필요 없어짐, 간단하고 직관적임
import React from 'react';
import styled from 'styled-components';

function App() {
	return (
		<div className="App">
			<MyStyled bgColor={"red"}>hello react!</MyStyled>
		</div>
	);
}

const MyStyled = styled.div`
	width: 50vw;
	min-height: 150px;
	padding: 10px;
	border-radius: 15px;
	color: #fff;
	&:hover {
		background-color: #ddd;
	}
	background-color: ${(props) => (props.bgColor ? "red" : "purple")};
`;

export default App;

 


가상돔

DOM (Document Object Model)

  • HTML의 단위 하나하나를 객체로 생각하는 모델
  • 트리 구조를 가짐
  • 수정이 일어날 때마다 모든 DOM을 조회해서 수정할 것을 찾고 전부 수정하면 연산이 많이 일어남 → 가상돔의 필요성

가상돔 (Virtual DOM)

  • 메모리 상에서 돌아가는 가짜 DOM
  • 기존 DOM과 새로 그린 DOM을 비교해서 바뀐 부분만 수정

라이프 사이클

  • 컴포넌트가 렌더링을 준비하는 순간 ~ 페이지에서 사라질 때까지

  • 컴포넌트 생성수정(업데이트)제거
  • 생성 : 처음으로 컴포넌트를 불러오는 단계
  • 수정(업데이트) : 사용자의 행동으로 데이터가 바뀌거나 부모 컴포넌트가 렌더링할 때 발생
  • ex. props가 바뀔 때, state가 바뀔 때, 부모 컴포넌트가 업데이트 되었을 때 (리렌더링), 강제로 업데이트했을 때 (forceUpdate())
  • 제거 : 페이지를 이동하거나 사용자의 행동으로 인해 컴포넌트가 화면에서 사라지는 단계

라이프 사이클 함수

  • constuctor() : 생성자 함수, 컴포넌트가 생성되면 가장 처음 호출되는 함수
  • render() : 컴포넌트의 모양을 정의하는 함수
  • componentDidMount() : 첫번째 렌더링을 마친 후에 실행, 리렌더링시에는 호출되지 않음 (컴포넌트가 화면에 나타나는 것 → 마운트(Mount) 한다고 표현함)
  • componentDidUpdate(prevProps, prevState, snapshot) : 리렌더링을 완료한 후 실행되는 함수, prevProps/prevState는 업데이트 전 props/state
  • componentWillUnmount() : 컴포넌트가 DOM에서 제거될 때 실행하는 함수, 컴포넌트에 이벤트 리스너를 등록했다면 반드시 해제해야 함
import React from 'react';

class LifecycleEx extends React.Component {
	//생성자 함수
	constructor(props) {
		super(props);
		this.state = {
			cat_name: '나비',
		};
		console.log('in constructor!');
	}

	componentDidMount() {
		console.log('in componentDidMount!');
	}

	componentDidUpdate(prevProps, prevState) {
		console.log(prevProps, prevState);
		console.log('in componentDidUpdate!');
	}

	componentWillUnmount() {
		console.log('in componentWillUnmount!');
	}

	render() {
		return (
			<div>
				<h1>고양이 이름은 {this.state.cat_name}</h1>
				<button onClick={this.changeCatName}>고양이 이름 바꾸기</button>
			</div>
		);
	}
}

export default LifecycleEx;
  • 라이프 사이클 함수는 클래스형 컴포넌트에서만 사용 가능함

Ref

  • 리액트에서 DOM 요소를 가져올 때 사용
class App extends React.Component {
	constructor(props) {
		super(props);
		this.state = {
			list: ['영화관 가기', '매일 책읽기', '수영 배우기']
		};
		this.text = React.createRef(); //ref 선언하기
	}

	componentDidMount() {
		console.log(this.text);
		console.log(this.text.current);
	}

	render() {
		return (
			<div className="App">
				...
				<input type="text" ref={this.text}/>
			</div>
		);
	}
}

 


클래스형 컴포넌트 state 관리

  • setState() : 클래스형 컴포넌트의 state를 업데이트할 때 사용하는 함수
  • 네모 추가/삭제 예제
더보기
import React from 'react';

class App extends React.Component {
	constructor(props) {
		super(props);
		this.state = {
			count: 3,
		};
	}

	componentDidMount() {}

	addNemo = () => {
		this.setState({count: this.state.count + 1});
	};

	removeNemo = () => {
		if (this.state.count > 0) {
			this.setState({count: this.state.count - 1});
		} else {
			window.alert('네모가 없습니다');
		}
	};

	render() {
		const nemo_count = Array.from({length: this.state.count}, (v, i) => i);
		console.log(nemo_count);
		return (
			<div className="App">
				{nemo_count.map((num, idx) => {
					return (
						<div
							key={idx}
							style={{
								width: '150px',
								height: '150px',
								backgroundColor: '#ddd',
								margin: '10px',
							})
						></div>
					);
		}}}

			<div>
				<button onClick={this.addNemo}>하나 추가</button>
				<button onClick={this.removeNemo}하나 빼기</button>
			</div>
		);
	}
}

export default App;
  • addNemo, removeNemo에서 count 상태를 수정함

 

함수형 컴포넌트에서 state 관리

  • 함수형 컴포넌트는 state가 없음
  • 그러나 react hooks를 사용하면 state를 가질 수 있음
  • useState()를 이용하여 state 관리
  • 네모 추가/삭제 예제
더보기
import React from "react";

const Nemo = (props) => {
	//setCount로 count라는 state 값을 수정함
  const [count, setCount] = React.useState(3); //useState로 초깃값 설정

  const addNemo = () => {
    setCount(count + 1); //setCount로 count 1 증가
  };

  const removeNemo = () => {
    setCount(count > 0 ? count - 1 : 0); //setCount로 count 1 감소
  };

  const nemo_count = Array.from({ length: count }, (v, i) => i);
  return (
    <div className="App">
      {nemo_count.map((num, idx) => {
        return (
          <div
            key={idx}
            style={{
              width: "150px",
              height: "150px",
              backgroundColor: "#ddd",
              margin: "10px",
            }}
          >
            nemo
          </div>
        );
      })}

      <div>
        <button onClick={addNemo}>하나 추가</button>
        <button onClick={removeNemo}>하나 빼기</button>
      </div>
    </div>
  );
};

export default Nemo;

 


이벤트 리스너 (Event Listener)

  • 사용자가 어떤 행동(이벤트)을 하는지 지켜보고 알려줌
  • 마우스 클릭, 터치, 마우스 오버, 키보드 누름 등의 이벤트
  • onClick처럼 엘리먼트에 직접 넣어주는 방법 or addEventListener을 통해 추가하는 방법이 있음

클래스형 컴포넌트에서 Event Listener 구독하기

  • DOM 요소가 있어야 이벤트 발생하는지를 지켜볼 수 있음 → componentDidMount()에서 작성
  • addEventListener() : 이벤트 등록 함수
  • removeEventListener() : 이벤트 제거 함수
constructor(props) {
	super(props);
	this.state = {
		count: 3,
	};
	this.div = React.createRef();
}

hoverEvent = (e) => {
	console.log(e.target);
	if (e.target.className === "App") {
		e.target.style.background = "#eee";
	}
}

componentDidMount() {
	console.log(this.div);
	//addEventListener로 이벤트 등록
	this.div.current.addEventListener("mouseover", this.hoverEvent);
}

componentWillUnmount() {
	//컴포넌트가 제거될 때 이벤트 지우기
	this.div.current.removeEventListener("mouseover", this.hoverEvent);
}

return (
	<div className="App" ref={this.div}>
		<Nemo/>
	</div>
);

+ Recent posts