🔑 Dispatch란?
- 디스패치는 스토어의 내장함수중 하나로 액션을 발생시키는 함수이다
- 함수는 액션(type과 payload(없어도됨)로 이루어진) 객체를 파라미터로 받는다.
- 그렇게 호출을 하면, 스토어는 리듀서 함수를 실행시켜서 해당 액션(객체의 type키를 가진 값)을 기준으로 처리하는 로직이 있다면 액션을 참고하여 새로운 상태를 만든다(반환한다).
🔑 Action이란?
- 스토어에 저장된 상태에 어떠한 변화가 필요하게 될 땐, 우리는 액션이란 것을 발생 시킨다
- 이는, 하나의 객체로 표현되는데, 액션 객체는 다음과 같은 형식으로 이뤄져있다.
{
type: "???",
payload: payload
}
export function ???(payload) {
return {
type: "??",
payload: payload
};
}
-
액션 생성함수를 만들어서 사용하는 이유는 나중에 컴포넌트에서 더욱 쉽게 액션을 발생시키기 위함이다
-
그래서 보통 함수 앞에 export
키워드를 붙여서 다른 파일에서 불러와서 사용한다.
-
액션생성 함수는 필수로 사용하지 않아도 되고 액션을 발생 시킬 때(dispatch 함수에 파라미터로 전달할때)마다 직접 액션 객체를 생성하여도 된다.
🔑 Redux Module - Ducks Pattern
-
리덕스 모듈:
- 액션 (Actions), 액션 생성 함수(Action Creators), 리듀서(Reducer)가 들어있는 자바스크립트 파일을 의미한다.
- 리덕스 모듈에선 리듀서는 default export 방식으로 내보내고, 액션 생성 함수는 export 키워드만 사용한다.
-
Redux 공식 문서에서는, ActionType, Action, Reducer 이 3가지를 따로 분리해서 다루기 때문에 액션을 하나만 추가하는 것도 매우 번거롭게 되어있다. (수정할 파일이 3개)
-
불편함을 해소하기 위해 Erik Rasmussen은 Redux의 끝글자 (dux)를 따서 Ducks 패턴을 만들었다.
- 액션 타입, 액션 생성 함수, 리듀서를 각각 별도의 파일(심지어는 별도의 폴더)에 분리하여 작성하기 보다는, 그 셋을 하나의 모듈처럼 한 파일 안에 작성하자는 제안이다.
-
덕스 패턴의 규칙은 아래와 같다.
- MUST export default a function called reducer()
- 반드시 리듀서 함수를 default export해야 한다.
- MUST export its action creators as functions
- 반드시 액션 생성 함수를 export해야 한다.
- MUST have action types in the form npm-module-or-app/reducer/ACTION_TYPE
- 반드시 접두사를 붙인 형태로 액션 타입을 정의해야 한다.
- ex.
const = CREATE_TODO = “CREATE_TODO”
- MAY export its action types as UPPER_SNAKE_CASE, if an external reducer needs to listen for them, or if it is a published reusable library
- 외부 리듀서가 모듈 내 액션 타입을 바라보고 있거나, 모듈이 재사용 가능한 라이브러리로 쓰이는 것이라면 액션 타입을 UPPER_SNAKE_CASE 형태로 이름 짓고 export 한다.
-
Ducks 패턴은 구조중심이 아니라 기능 중심
으로 파일을 나눈다.
- 단일기능을 작성할때나 기능을 수정할 때 하나의 파일만 다루면 되므로 직관적인 코드작성이 가능하다.
🔑 props.children
- 리액트 공식 문서에는
props.children
에 대해 아래와 같이 설명한다.
어떤 컴포넌트들은 어떤 자식 엘리먼트가 들어올지 미리 예상할 수 없는 경우가 있습니다. 범용적인 ‘박스’ 역할을 하는 Sidebar 혹은 Dialog와 같은 컴포넌트에서 특히 자주 볼 수 있습니다.
- 주로 자식 컴포넌트 또는 html의 요소들이 어떻게 구성되어 있는지 모르는 상태에서 화면에 표시해야 하는 경우에 사용한다.
- 여는 태그와 닫는 태그가 있는 JSX 표현에서 두 태그 사이의 내용을
props.children
로 넘기는 경우도 있다.
- React는
child
를 사용하지 않는 경우 닫는 태그를 생략할 수 있다.
function FancyBorder(props) {
return (
<div className={'FancyBorder FancyBorder-' + props.color}>
{props.children}
</div>
);
}
props.children
은 한개, 여러개, 혹은 0개의 child node를 가질 수 있고, 그런 부분에서 자유도가 높고 신경쓸 문제가 없기 때문에 자주 사용한다.
- 중복되는 코드를 처리할때도 유용하다.
- 동일한 < img > 태그를 여러번 중복해서 사용하는거보다,
<ImageSlider>
<img src="/assets/img-1.pg" />
<img src="/assets/img-2.pg" />
<img src="/assets/img-3.pg" />
</ImageSlider>
export default function ImageSlider(props) {
return (
<div className="img-slider">
{props.children}
</div>
);
}
props.children
으로 처리하는 것이 더 깔끔하다.
🔑 Flux 패턴
- Flux는 사용자 입력을 기반으로 Action을 만들고 Action을 Dispatcher에 전달하여 Store(Model)의 데이터를 변경한 뒤 View에 반영하는 단방향의 흐름으로 애플리케이션을 만드는 아키텍처이다
Action
- Action이란 데이터를 변경하는 행위로서 Dispatcher에게 전달되는 객체를 의미한다.
- Action creator 메서드는 새로 발생한 Action의 타입(type)과 새로운 데이터(payload)를 묶어 Dispatcher에게 전달한다.
{
type: 'SET_PROFILE',
data: {
'name': 'Harry',
'age': 458
}
}
Dispatcher
- Dispatcher는 모든 데이터의 흐름을 관리하는 중앙 허브다.
- Dispatcher에는 Store들이 등록해놓은 Action 타입마다의 콜백 함수들이 존재한다.
- Action을 감지하면 Store들이 각 타입에 맞는 Store의 콜백 함수를 실행하고, Store의 데이터를 조작하는 것은 오직 Dispatcher를 통해서만 가능하다.
- 또한 Store들 사이에 의존성이 있는 상황에서도 순서에 맞게 콜백 함수를 순차적으로 처리할 수 있도록 관리하는 역할도 수행한다.
Store (Model)
- Store는 상태 저장소로서 상태와 상태를 변경할 수 있는 메서드를 가지고 있다.
- 어떤 타입의 Action이 발생했는지에 따라 그에 맞는 데이터 변경을 수행하는 콜백 함수를 Dispatcher에 등록한다.
- Dispatcher에서 콜백 함수를 실행하여 상태가 변경되면 View에게 데이터가 변경되었음을 알린다.
View
- View는 리액트 컴포넌트를 의미한다.
- Store에서 View에게 상태가 변경되었음을 알려주면 최상위 View(Controller View)는 Store에서 데이터를 가져와 자식 View에게 내려보낸다.
- 새로운 데이터를 받은 View는 화면을 리렌더링하고, 사용자가 View에 어떤한 조작을 하면 그에 해당하는 Action을 생성한다.
- 각 요소들은 단방향 흐름에 따라 순서대로 역할을 수행하고, View로부터 새로운 데이터 변경이 생기면 처음부터 다시 이 순서대로 실행한다.
- 이렇게 함으로써 예외 없이 데이터를 처리할 수 있게 된다.
좋은 팀원들 덕분에 이번 주차에도 많은 것을 얻어갈 수 있었다!