리액트 기초강의 배운내용 정리

bella·2022년 1월 30일
0


📌 리액트의 장점

✔ Virtual DOM을 이용한다.
✔ 이미 많은 곳에서 사용하고 있다.
✔ 다양한 라이브러리가 존재한다.
✔ 라우터, 상태관리, 스타일링 등 기능들이 내장되어 있지 않고 써드파티 라이브러리가 존재한다.
(자유도가 높아 원하는 방식을 선택해 사용할 수 있다.)


📌 리액트 프로젝트 시작하기

✔ Node, yarn, Webpack, Babel 등의 도구를 설치하여 프로젝트 설정하기
✔ 페이스북에서 제공하는 create-react-app 을 통해 설치하면 위 작업을 간단하게 준비할 수 있다.
✔ Webpack : 여러가지의 파일로 저장된 컴포넌트들을 한 개로 결합해주는 역할
✔ Babel : JSX를 비롯한 새로운 자바스크립트 문법들을 사용할 수 있게 해주는 역할

  1. 노드 공식 홈페이지를 통해 Node.js 설치하기
  2. yarn 설치 페이지를 통해 yarn 설치하기
  3. 코드 에디터 준비하기 (VSCode, Atom, WebStorm, Sublime ..)
  4. 터미널창에서 create-react-app 생성 'yarn create react-app [폴더명]'
  5. 'yarn start'

📌 조건부 렌더링

✔ JSX 내부에서 조건부 렌더링을 할 때는 보통 삼항연산자 혹은 AND 연산자를 사용한다.

{
  1 + 1 === 2 && (<div>맞아요!</div>)
}

✔ if문을 사용하려면 즉시 실행 함수 표현(IIFE)을 사용해야 한다.

{
  (() => {
    if (value === 1) return (<div>하나</div>);
    if (value === 2) return (<div></div>);
    if (value === 3) return (<div></div>);
  })()
}

📌 props

✔ 부모컴포넌트에서 자식 컴포넌트로 값을 전해줄 때 props를 이용

//App.js 부모컴포넌트
return(
  <Myname name="bella">자식요소</>
)
//Myname.js 자식컴포넌트
return(
  <>
     <h1>제 이름은 {this.props.name} 입니다.</h1>
     <h2>이것은 {this.props.children} 값입니다.</h2>
  </>
)
//Result
     ➡ 제 이름은 bella 입니다. 
     ➡ 이것은 자식요소 값입니다.

✔ PropTypes를 이용해 타입 설정
- import PropTypes from "prop-types"; 상단에 추가해주기

//Myname.js
class Myname extends Component {
...
}
Myname.propTypes = {
    name: PropTypes.string.isRequired
}

✔ defaultProps를 이용해 기본값 설정

//Myname.js
class Myname extends Component {
...
}
Myname.defaultProps = {
   name: "unkown",
   children: "자식요소"
}

📌 state

✔ 동적인 데이터를 다룰 때 사용

📍 스테이트 정의

//class fields 문법
class Counter extends Component {
	state = {
		number: 0,
	}
    ...
}
//constructor를 작성하게 되면 기존 클래스 생성자를 덮어쓰게 됨
// -> super(props) 를 호출해주어 리액트 컴포넌트가 가지고 있던 생성자를 미리 실행해줘야 함
class Counter extends Component {
  constructor(props) {
    super(props);
    this.state = {
      number: 0
    }
  }
  ...
}
❓ class fields 와 constructor 를 동시에 사용한다면?
class fields 가 먼저 실행되고, 그 다음에 constructor 에서 설정된 것이 실행

📍 메소드 작성

 handleIncrease = () => {
    this.setState({
      number: this.state.number + 1
    });
  }
  handleDecrease = () => {
    this.setState({
      number: this.state.number - 1
    });
  }
화살표 함수를 이용하지 않을경우 클릭이벤트 발생 시, this가 undefined으로 나타나 제대로 동작하지 않게 된다.
이를 방지하기 위해선 constructor에 아래 코드를 추가해줘야 한다.
constructor(props) {
    super(props);
    this.handleIncrease = this.handleIncrease.bind(this);
    this.handleDecrease = this.handleDecrease.bind(this);
  }

📍 setState

- state 값을 바꾸기 위해 사용하는 함수, 객체로 전달되는 값만 업데이트를 해준다.
- 리액트에서는 setState 함수가 호출될때마다 컴포넌트가 리렌더딩 되도록 설계되어 있다.
- 객체의 깊숙한곳까지 확인하지는 못한다
state = {
    number: 0,
    foo: {
      bar: 0,
      foobar: 1
    }
  }
this.setState({
  foo: {
    foobar: 2
  }
})
//Result : 기존 foo 객체가 변경됨
{
  number: 0,
  foo: {
    foobar: 2
  }
}
- 기존값을 유지하면서 변경하려면 전개연산자(...)를 이용
this.setState({
  number: 0,
  foo: {
    ...this.state.foo,
    foobar: 2
  }
});
- 객체대신 함수 전달하기 비구조화 할당
 handleIncrease = () => {
    const { number } = this.state;
    this.setState({
      number: number + 1
    });
  }
  handleDecrease = () => {
    this.setState(
      ({ number }) => ({
        number: number - 1
      })
    );
  }

📌 LifeCycle API

✔ 컴포넌트가 브라우저에서 나타날때, 사라질때, 그리고 업데이트 될 때, 호출되는 API

📍 컴포넌트 초기생성

constructor(props) {
super(props);
// 컴포넌트가 새로 만들어질 때마다 호출되는 컴포넌트 생성자 함수
}
componentWillMount() {
// 컴포넌트가 브라우저에 나타나기 직전에 호출되는 API
// 기존에 해당 API가 하던 일을 constructor와 componentDidMount에서 처리가 가능
// 해당 API는 더이상 필요하지 않게 됨
// v16.3 이후로는 'UNSAFE_componentWillMount()'라는 이름으로 사용
}
componentDidMount() {
// 컴포넌트가 브라우저에 나타났을 때 호출되는 API
// DOM을 사용해야 하는 외부 라이브러리 연동 : D3, masonry, etc
// 컴포넌트에서 필요한 데이터 요청: Ajax, GraphQL, etc
// DOM 에 관련된 작업: 스크롤 설정, 크기 읽어오기 등
}

📍 컴포넌트 업데이트

componentWillReceiveProps(nextProps) {
// 컴포넌트가 새로운 props를 받게됐을 때 호출되는 API
// this.props는 아직 바뀌지 않은 상태, 새로 받게될 props는 nextProps로 조회
// 주로 state가 props에 따라 변해야하는 로직을 작성
// v16.3 이후로는 'UNSAFE_componentWillReceiveProps()'라는 이름으로 사용
// 상황에 따라 getDerivedStateFromProps로 대체가능
}
static getDerivedStateFromProps(nextProps, prevState) {
// v16.3 이후에 만들어진 라이프사이클 API
// props 로 받아온 값을 state 로 동기화 하는 작업을 해줘야 하는 경우에 사용
// setState 하는 것이 아닌, 특정 props가 바뀔 때 설정하고 싶은 state값을 리턴하는 형태로 사용
  if (nextProps.value !== prevState.value) {
    return { value: nextProps.value };
  }
}
shouldComponentUpdate(nextProps, nextState) {
// 기본적으로 true를 반환, return false 하면 업데이트를 안함
// return this.props.checked !== nextProps.checked
}
componentWillUpdate(nextProps, nextState) {
// shouldComponentUpdate 에서 true 를 반환했을때만 호출
// 주로 애니메이션 효과를 초기화하거나, 이벤트 리스너를 없애는 작업을 진행
// 해당 함수가 호출된 이후, render()가 호출됨
// v16.3 이후로 사용되지 않음, getSnapshotBeforeUpdate로 대체 가능
}
getSnapshotBeforeUpdate(prevProps, prevState) {
// DOM 변화가 일어나기 직전의 DOM 상태를 가져옴
// 여기서 리턴하는 값은 componentDidUpdate 에서 3번째 파라미터로 받아올 수 있음
// 해당 API가 발생하는 시점 :
// render(), getSnapshotBeforeUpdate(), 실제 DOM에 변화 발생, componentDidUpdate
}
componentDidUpdate(prevProps, prevState, snapshot) {
// render()를 호출하고 난 다음에 발생
// this.props 와 this.state 가 바뀌어있는 상태
// 파라미터를 통해 이전 값, prevProps와 prevState 조회 가능
// getSnapshotBeforeUpdate에서 반환한 snapshot값을 세번째 파라미터로 받아옴
}

📍 컴포넌트 제거

componentWillUnmount() {
// 이벤트, setTimeout, 외부 라이브러리 인스턴스 제거
}

📍 컴포넌트 에러 발생

componentDidCatch(error, info) {
  this.setState({
    error: true
  });
}
render() {
  if (this.state.error) return (<h1>에러발생!</h1>);
}



profile
기록하며 공부하기

0개의 댓글