[TIL 2023.03.09] Redux 주요 개념 / HTML의 inline, block 요소

김헤일리·2023년 3월 9일
0

TIL

목록 보기
30/46

지식 보충을 위해 조금씩 정리해보자! #9


1. Redux의 주요 개념

❓ Redux란?

예전에 정리했던 내용: [Redux] Redux, Redux-Toolkit, Axios 개념 복습

공식 문서에 따르면 Redux는 자바스크립트 앱을 위한 예측 가능한 상태 컨테이너라고 한다.
리덕스를 사용하는 가장 큰 이유는 리액트에서 컴포넌트가 많아질수록 구조가 복잡해져서 상태 변경을 하기 어려워지기 때문이다. 리덕스를 사용할 경우 데이터가 Store에 저장되기 때문에 props drilling이 발생하지 않는다.

리덕스는 쉽게 설명하면 상태 관리의 로직을 컴포넌트 밖에서 처리 하는 것이다.
리덕스는 이전상태와 새로운상태의 메모리 주소를 비교하여 주소가 같으면 아무런 변경이 없다고 판단하여 상태가 업데이트되지 않는다. 새로운 상태값은 이전 상태값를 복사한 후에 가공해서 새로운 상태를 반환해야 변경을 감지한다. (리액트의 state 변경과 같음)

리덕스의 흐름

  1. 사용자의 행동은 Action으로서 state에 변화를 준다.
  2. 발생한 Action은 Dispatcher라는 캐리어가 리덕스 스토어에 전달한다.
  3. Dispatcher가 보낸 Action은 Reducer라는 함수에 도착하고, Reducer는 Action
  4. state를 저장하고 있는 Store는 Reducer로 인해 State를 변경시킨다.
  5. State가 변경되면 렌더링이 발생하고 사용자에게 변경된 상태가 표시된다.
  • 리덕스 또한 데이터 흐름은 단방향이다.

❓ Redux 외의 상태관리 도구

가장 많이 사용되는 상태관리 도구는 단연 Redux, Redux-Toolkit이지만, 프로젝트의 성격이나 규모에따라 상태관리 라이브러리를 사용한다고 한다. 특히 리액트의 경우, 자체적으로 제공하는 context API가 있는만큼, 사용할 수 있는 상태관리 도구는 다양하다.

Context API

  • Context API는 리액트에서 만든, React 컴포넌트 트리 안에서 전역 상태를 공유할 수 있도록 만들어진 방법이다. 전역 상태 관리의 측면에서 다른 도구들과 다르게 상태들을 직접적으로 관리해주지 않고, 단순히 이미 존재하는 상태를 다른 컴포넌트들과 쉽게 공유할 수 있게 해주는 역할을 한다. 이런 Context API는 중간에 있는 Element들에게 props를 넘겨주지 않고도 데이터를 가져다가 사용할 수 있기 때문에 (Prop Drilling을 피할 수 있다.) 테마나 언어 등 전역적으로 쓰이는 데이터들을 사용할 때 자주 쓰인다.

Context API는 Context, Provider, Consumer로 설명할 수 있다.

  1. Context는 전역 상태를 저장하는 곳이다. Context 내부에 Provider와 Consumer가 정의되어있고, Consumer는 Context를 통해서 상태에 접근이 가능하다.

  2. Provider는 전역 상태를 제공하는 역할을 한다. Context에 상태를 제공해서 다른 컴포넌트가 상태에 접근할 수 있도록 도와준다. 제공된 상태에 접근하기 위해서는 Provider 하위에 컴포넌트가 포함되어있어야한다.

  3. Consumer는 제공받은 전역 상태를 받아서 사용하는 역할을 한다. Context는 Consumer 사이에 있는 첫 객체를 Context에 인자로 전달하기 때문에, 바로 JSX를 작성하면 안되고, 빈 객체를 작성하고나서 JSX를 작성해야한다.


MobX

  • React와 함께 사용하는 상태 관리 라이브러리중 Redux와 MobX가 가장 많이 사용되고 있다. Redux와 다르게 여러개의 store를 가질 수 있고, typescript 기반으로 만들어져있다.

  • 상태를 변경하기 위해서 event와 같은 action(행동)이 발생하면 상태(Observable)가 update되고, 상태가 변경되었음을 notify해서 필요에 따라 연산된 값(Compute Values)을 계산하거나 적절한 reaction(반응)을 수행한다.
  1. State : 관찰 받고 있는 상태

    • MobX 를 사용한 상태관리 데이터는 Observable하다.
    • MobX에서 상태는 관찰 할 수 있는 상태이며, 관찰하고 있는 상태가 변경되었을 때 특정 작업을 수행할 수 있다.
  2. Reactions : 반응

    • Reactions는 Observable State의 값이 변경되었을 때 수행한다.
    • Observable State 의 내부의 값이 바뀔 때 마다 자동으로 특정 작업(Side Effect)을 수행하도록 Reactions을 정의할 수 있다.
    • Observable State의 값을 변경할 때는 action을 사용하도록 강제하고 있으며 MobX의 설계상 action을 사용하는 것이 바람직해 보인다.
  3. Actions : 액션

    • Action(행동)은 Observable state에 변화를 일으키는 것
    • Obeservable State의 값을 변경하는 상태변경 함수를 이용해서 상태를 변경하고, 변경된 상태에 따라 자동으로 사이드 이펙트를 일으키는 것이 MobX의 핵심 동작이며 개념이다.
    • 기본적으로 action을 사용하지 않고, 상태를 변경하는 것을 MobX에서는 허용하지 않는다.
    • 이를 강제함으로써 상태변화을 일으키는(Side Effect) 부분을 명확하게 한다.
  4. Derivation(Computed Values) : 파생된 값 (연산된 값)

    • 어플리케이션에서 유지하는 상태 값을 그대로 이용하는 경우도 있지만, 이 상태 값을 바탕으로 특정 값을 계산해야할 경우도 존재한다.
    • Computed Value(연산된 값)은 필요에 의해 특정 상태 값을 기반으로 자동으로 연산되어지는 값을 의미한다.
    • 특정 상태 값을 기반으로 Computed Value(연산된 값)를 자동으로 계산하여 사용할 수 있게 해주며, 연산에 사용된 특정 상태 값을 관찰하여 값이 변할 때 마다 자동으로 계산하여 사용할 수 있게 해준다.
      • ex) 학생들의 성적(점수, 총합 점수, 평균)을 상태관리한다면 학생들의 점수가 변경될 때마다 총합점수, 평균 값은 다시 계산되어야한다.
    • Computed Value(연산된 값)는 관찰하고 있는 특정 상태 값이 변경 되었을 때 다시 계산하지만, 특정 상태 값이 변경 되었을 때 Computed Value(연산된 값)의 결과가 변하지 않는다면 다시 계산하지 않는다. (중요)
  1. autorun

    • autorun 으로 전달하는 콜백 함수에서 Obeservable State의 값이 사용되고 있으면 자동으로 그 값을 관찰하여 그 값이 바뀔 때 마다 콜백 함수가 실행된다.
  2. transaction

    • action들을 transaction 단위로 묶어서 실행할 수 있다.
    • transaction 단위로 묶인 모든 action이 실행된 이후, 최종 상태 값에 대해 Side Effect가 발생한다.

React Query

전역 상태관리 라이브러리라고 보기보다는, 서버와 클라이언트 간 비동기 작업을 쉽게 다룰 수 있게 도와주는 라이브러리다. 서버상태를 관리하는 라이브러리라고 생각하면 된다. 프론트엔드에서 어려운 부분 중 하나가, 이렇게 비동기를 통해 서버 상태를 가져오고 관리하고 업데이트 하는 부분인데, 그 부분을 쉽게 해준다.

  • 어플리케이션 내에 속하지 않고, 그러므로 제어하지도 못한다. 보통은 원격에 위치한 곳에 저장되어있다.
  • 데이터를 가져오거나 업데이트를 하기 위해서는 비동기 API가 필요하다.
  • 나만 사용하는 것이 아니라, 다른 사람들과 함께 사용하기 때문에 언제 어떻게 Update 될 지 모른다.
  • 그러므로 내가 당장 어플리케이션에서 사용하는 데이터가 Outdated 상태가 될 수 있다.
    (클라이언트는 서버 데이터의 snapshot만을 사용하기 때문에, 클라이언트에서 보이는 서버 데이터는 항상 최신이라고 보장할 수 없다.)

React Query는 useQuery hook의 파라미터를 통해 다양한 기능을 제어할 수 있다.

  • API 데이터의 만료시간
  • 데이터를 캐시에서 유지할 시간
  • 브라우저를 focus할 때, 데이터를 리프레시 할 것인지에 대한 여부
  • 리프레시 간격
  • 데이터 가져오는 것에 대한 성공, 로딩, 에러 콜백 등..

Recoil

Recoil는 React를 위한 상태 관리 라이브러리다. recoil 상태를 사용하는 컴포넌트는 부모 트리 어딘가에 나타나는 RecoilRoot 가 필요하다. 루트 컴포넌트가 RecoilRoot를 넣기에 가장 좋은 장소다.

  1. Atom
  • Atom은 상태(state)의 일부를 나타낸다.
  • Atoms는 어떤 컴포넌트에서나 읽고 쓸 수 있다.
  • atom의 값을 읽는 컴포넌트들은 암묵적으로 atom을 구독하기 때문에 atom에 어떤 변화가 있으면 그 atom을 구독하는 모든 컴포넌트들이 리렌더링된다.
  • 컴포넌트가 atom을 읽고 쓰게 하기 위해서는 useRecoilState()를 사용한다.
  1. Selector
  • Selector는 파생된 상태(derived state)의 일부를 나타낸다.
  • 파생된 상태는 상태의 변화다. 파생된 상태를 어떤 방법으로든 주어진 상태를 수정하는 순수 함수에 전달된 상태의 결과물로 생각할 수 있다.
  • useRecoilValue() 훅을 사용해서 state를 읽을 수 있다.


2. HTML의 inline, block 요소

CSS의 display 속성은 기본적으로 inline 값을 갖지만, 브라우저는 기본적으로 div 등
블록 요소로 구분되는 요소들의 display 속성값을 block으로 지정한다.

❓ Block 요소

블록 요소는 모든 인라인 요소를 포함할 수 있고 다른 블록 요소도 일부 포함 할 수 있다.
기본적으로 가로폭 전체의 넓이를 가지는 직사각형 형태가 되며 width, height, margin, padding 등을 사용하여 레이아웃을 수정할 수 있다. 블록 요소 다음에 다른 블록 요소를 추가할 경우, 줄바꿈이 이뤄진다.

대표적인 예시: <div>, <h1> ~ <h6>, <p>


❓ Inline 요소

인라인 요소는 항상 블록 요소안에 포함되어있고 인라인 요소안에 다른 인라인 요소가 포함된다. 기본적으로 컨텐츠가 끝나는 지점까지를 넓이로 가진다. width, height로 레이아웃에 변형을 줄 수가 없는 대신 line-height로 줄의 높낮이를 조절할 수 있고 text-align으로 텍스트의 종앙, 좌,우측 정렬을 할 수 있다. 인라인 요소 다음에는 줄바꿈이 없고 우측으로 바로 이어서 표시된다.

대표적인 예시: <a>, <b>, <br>, <em>, <input>, <label>, <textarea>


❓ Inline-block 요소

inline과 block의 특징을 모두 가진 요소다. 외부는 inline, 내부는 block처럼 표시할 수 있고, inline에서 불가능하던 width와 height 지정 및 margin, padding 의 상하 간격 지정이 가능하다. inline-block을 이용하면 여러 개의 요소들을 한 줄에 원하는 너비만큼 배치 가능 하기 때문에 레이아웃을 구성할 때 활용한다.

인라인 요소의 display를 inline-block으로 변경할 경우 적용된다.


blockinlineinline-block
기본 너비부모의 너비만큼컨텐츠만큼컨텐츠만큼
width, height 속성적용무시무시
가로공간 차지독점공유공유
margin 속성가로만가로세로 모두 적용 (상하 상쇄)가로세로 모두 적용
padding 속성가로만 적용, 세로는 배경색의 경우만가로세로 모두 적용가로세로 모두 적용

출처:

profile
공부하느라 녹는 중... 밖에 안 나가서 버섯 피는 중... 🍄

0개의 댓글