파이썬에는 익숙하지만 웹 프론트엔드 패러다임은 처음이니까, 그런 입장에서 이들에게 특징적이라고 여겨지는 부분을 한번 정리해봤다.
변수 선언 시, 불변할 경우(대부분) const
, 변경이 필요할 경우 let
으로 선언. var
는 레거시.
파이썬의 사전 타입과 비슷한 포지션이면서도 더 광범위한 역할을 한다. 사전의 데이터 저장과 클래스의 객체 역할까지 수행.
웹 브라우저의 런타임에는 미리 준비된 객체들(console.log()
의 console
, document
, localStorage
등)이 있다. 파이썬으로 치자면 re
, datetime
과 같은 표준 라이브러리가 되겠다.
이처럼 클라이언트 사이드에는 프론트엔드 개발자가 작업 시 활용할 수 있는 프로그래밍 인터페이스인 Web API가 구비되어 있다. 브라우저에서 발생하는 이벤트를 감지하고 그에 따른 반응을 해주는 작업 역시 Web API를 활용해 이루어짐. 자바스크립트 작업 시에는 이들 객체들이 무엇이 있고 무엇이 유용한지 알고있는 것이 중요.
그 중에서도 DOM(Document Object Model)은 HTML 문서의 요소에 접근할 수 있도록 추상화한 객체(이자 인터페이스). HTML 문서 소스 전체와 대응되는 document
객체를 활용하면 내부 HTML 요소들에 대응하는 개별 DOM 객체에 접근해 미리 구비된 관련 인터페이스를 활용해 다양한 작업을 할 수 있다(ex. 위에서 말한 이벤트 리스닝).
파이썬과 달리 비동기 방식으로 설계된 언어이기 때문에 비동기 처리를 할 일이 많다. 따라서 로직 자체를 함수의 형태로 전체 흐름 사이사이에 전달하고 넘겨 받는 방식이 많다. 해당 함수는 비동기 프로세스에 따라 이후 적절한 시점에 실행되기 때문에 이런 방식을 콜백이라 함.
...
) 사용리액트는 애플리케이션의 작동 과정에서 그때그때 UI를 렌더링하는 데 필요한 상태(데이터) 관리를 해줌. 컴포넌트 내부의 상태값(state)과 외부(부모 컴포넌트로부터 자식 컴포넌트로 전달)로부터 받은 속성값(props)을 사용해 관리. 기본적으로 이들 값이 변경됐을 때마다 해당하는 컴포넌트를 다시 그리는 방식으로 작동.
리액트 앱 개발자의 입장에서 작성하게 될 코드가 선언적임. 브라우저에서 실행되는 복잡한 작업을 순서대로 명령하는 것이 아니라, 보여질 UI 컴포넌트를 syntax에 맞춰 미리 선언해두면, 데이터(state+props) 변경이 일어났을 때 해당 UI 컴포넌트를 그리기 위해 실행되어야 할 작업은 리액트가 알아서 조율해줌.
리액트 엘리먼트는 리액트 컴포넌트(함수형)가 리턴하는 자바스크립트 Plain Object. 하나의 DOM 요소의 형태로 리액트 컴포넌트가 그리는 최종 화면을 표현.
리액트 컴포넌트(함수형)는 데이터를 담당하는 props와 state을 일련의 로직에 따라 가공 후, 최종적으로는 결과 화면으로서 리액트 엘리먼트를 리턴하는 자바스크립트 함수. 리액트 컴포넌트는 재사용 가능한 UI 모듈이 되어 이들의 조합으로 전체 프론트엔드를 표현한다.
React Component = props + state + React Element + 로직
함수형 컴포넌트로 클래스 컴포넌트를 대체할 수 있도록, 함수형 컴포넌트 안에서 사용하면 기존 클래스 컴포넌트에서처럼 React state와 생명주기 기능을 연동할 수 있게 해주는 리액트의 API. 함수형 컴포넌트가 비록 함수지만 그 안의 일부분인 로컬한 데이터와 로직을 글로벌한 리액트 환경에서 접근해 관리하는 방식. 그 결과 상태 관련 로직을 모듈화해 재사용할 수 있고 리액트 컴포넌트 코드의 복잡성이 확 줄어든다.
함수형 컴포넌트 안에서 로컬한 상태값(state)을 생성해 내내 독립적으로 관리할 수 있도록 해준다. 초기값을 넣어 useState
훅을 호출하면 그 결과 값으로 현재 state 값을 참조할 수 있는 변수와 수정을 위한 setter 함수가 순서대로 들어있는 배열을 리턴.
리액트 컴포넌트의 생명주기에서 특정한 순간마다 미리 정해둔 side effect(DOM을 직접 조작하거나 HTTP 요청을 보내는 등 해당 컴포넌트를 렌더하는 것 이외의 추가 동작)를 실행할 수 있도록 해준다.
componentDidMount
)componentDidUpdate
)componentWillUnmount
)위의 세 가지 순간에 서로 다른 두 가지 로직이 수행
리액트 앱을 만들 때 개발과 배포에 필요한 모든 라이브러리들을 한데 모아 프로젝트 폴더를 셋업해주는 CLI 툴. 생성된 프로젝트 안에 webpack, babel, eslint 등 기본 설정되어 있음.
리덕스 역시 애플리케이션 상태 관리를 위한 라이브러리. 만약 리액트가 있음에도 리덕스가 필요하다면 그건 애플리케이션이 커지면서 상태값이 변경될 때 발생하는 데이터 흐름이 양방향으로 복잡해지는 경우. 그럴 때, 단방향 데이터 흐름을 리덕스를 통해 구축함으로써, 예측 가능하고 중앙화된 상태 관리를 달성한다.
실질적으로는 서로 다른 컴포넌트 사이에 상태를 공유해야 하는데 트리 구조가 깊어져 부모로부터 자식으로 props를 여러 번 넘겨줘야 할 때, 그 대신 리덕스의 글로벌한 store에서 상태값을 중앙화해 관리하고 여러 컴포넌트마다 개별적으로 이에 접근하는 방식으로 사용됨.
하나의 애플리케이션에는 하나의 중앙화된 스토어만 존재. 그리고 그 안에 상태값을 저장할 state
도 하나의 Object 타입 객체. 따라서 다양한 상태값을 저장하려면 state
객체 안에 key-value로 일일이 정의해야 함. 스토어를 구성하는 것은 단일한 state
객체 이외에도 리덕스 작동에 필요한 여러 미들웨어 설정 등이 있음.
상태값의 수정은 오로지 리듀서를 통해서만 가능. 리듀서는 직전 상태의state
객체와 이번에 수행할 action
객체 두 인자를 받아 새로운 state
객체를 반환하는 순수 함수. action.type
값을 기준으로 케이스 처리를 거쳐 전체 state
중 해당 액션이 필요로 하는 부분만 수정 로직을 수행. 그리고 마지막엔 부분 수정된 전체 state
의 복사본을 다시 리턴.
상태값 수정과 관련된 정보를 담고 있는 객체. 일반적으로 {"type": ACTION_NAME, "payload": ACTION_VALUE}
의 형태로 고정. 일관성 있는 action.type
문자열 관리를 위해 보통 특정 액션 객체마다 생성 함수를 따로 정의해서 사용함.
리덕스에서 실제 상태값 수정이 필요한 순간에 호출하는 유일한 함수. 디스패치 과정을 통해 리덕스는 중앙화된 스토어에 상태값 변화를 일괄적으로 수행.
리듀서와 함께 정의된 스토어가 이미 있다면, 상태값 수정이 필요한 곳에서 해당 스토어 객체의 메소드로써 사용할 수 있다. 액션만 넣어 store.dispatch
를 호출하면 리덕스가 여기에 직전 state
를 더해 리듀서를 호출해 상태값 수정 로직을 수행한다.
리액트와 함께 리덕스를 사용하기 위해 사용하는 API. 리액트 컴포넌트 안에서 리덕스의 state
객체와 dispatch
함수를 사용하기 위해 이를 props의 형태로 넘겨주는 방식으로 사용.
기본 리덕스가 야기하는 보일러플레이트 코드를 줄이기 위해 사용하는 API. 코드 양이 확실히 줄어든다.