19. 기본 HTML 버튼은 그냥 좀 구려요.
아이콘도 없구요
그래서 버튼의 색상도 바꾸고
아이콘도 넣고 싶어요
버튼을 컴포넌트로 만들면 props 에는 아이콘과 스타일을 넣어볼수 있습니다.
<Button icon=‘power’ style={…}>Click me!</Button>
33. 라우터를 이용한 컴포넌트 분리
중첩 라우터를 이용해
집중할 관심사를 완전히 분리한다.
:
( )(
./ ( )(
./
(/
( )(
./ ( )(
( )(
./ ( )(
/
/ (
34. 라우터를 이용한 컴포넌트 분리
라우터가 로드할 페이지를 결정할때 중첩
된 부모 페이지가 있으면 같이 로드된다.
C
( )(
./ ( )(
./
(/
( )(
./ ( )(
( )(
./ ( )(
:
/ (
부모는 자식이 필요로 하는
값이 없으면 아예 랜더링을 하지 않는다.
즉, 선택적으로 Props를 주입할수있다.
35. 라우터를 이용한 컴포넌트 분리
1. 중첩된 부모 라우터에서 필요한 값을 한번만 로드한다.
2. 자식 라우터에는
로드된 값을 선별해서
값이 있을때만 주입하고 랜더링한다.
3. 이렇게 하면 자식 라우터는 필요한 값을 항상
주입 받은 상태로 넘어오기 때문에 기다릴 필요
가 없게된다.
C
( )(
./ ( )(
./
(/
( )(
./ ( )(
( )(
./ ( )(
:
/ (
36. 사용자 이벤트 처리는 누가 하지?
Redux를 이용한 컴포넌트 분리
click! 컨테이너까지 이벤트를 올려주세요!
스토어를 연결한 컨테이너를 중간중간 만든다.
이벤트 처리는 여기서 하기로 하자!
) ( ).
) ( ).
) ( ).
) ( ).
) ( ).
) ( ).
37. 사용자 클릭 이벤트
Redux를 이용한 컴포넌트 분리
click!
이벤트 처리는 역시 dispatch 액션!!
. .
. .
. .
. .
. .
. .
)
. (
그럼에도 불구하고 콜백을 올리는건
여전히 귀찮다…
38. Redux를 이용한 컴포넌트 분리
콜백이 귀찮을땐 dispatch를 내려준다.
. .
. .
.
.
)
. (
39. Redux를 이용한 컴포넌트 분리
너무 깊어 dispatch도 내려주기 귀찮을땐
context 매직을 사용한다.
export default class BookNoteList extends React.PureComponent {
static contextTypes = {
store: React.PropTypes.object
};
render() {
return(
<div>
<Button
onClick={
()=> this.context.store.dispatch(액션)
}
> 컨텍스트 쓰지말래도 난 쓸꺼야! </Button>
</div>
)
}
}
Provider를 이용해 주입한 store 컨텍스트를 사용할수있다.
. .
. .
)
. (
40. Redux와 컴포넌트를 연결하는 방법
connect(mapStateToProps, mapDispatchToProps)(ContainerComponent)
connect(mapStateToProps)(ContainerComponent)
dispatch 내리면 코드가 간결해진다.
단점, redux에 의존성이 생긴다.
어짜피 재사용하기 힘들다면 GoGo!
(
(
)
)
42. React는 빙산의 일각 리마인드
브라우저(글로벌) 영역
애플리케이션 영역
리덕스 영역
Middleware Control Flow
. E A A E A I - E /
l pSh
/
E E
EC
. )/ )/
pSh MS
( A A
( C A
EC AA
E
E E
/) .
iMS
E
sRf T rk
Pao f
E
Lj
. E A
( A A
C CE
gc
E C CE
/
e
사용자
A
(
Pao
/
e / OP V
EC A
A A
,
Lj
pSh
E EE A
mn
d
bU
A
Lj
EC A
이제 겨우 요거 했다!
43. 재사용 가능한 컴포넌트란?
2. 프로젝트 내에서 컨테이너도 재사용하고 싶다면.
1. 프로젝트 내에서 뷰를 재사용하고 싶다면
3. 다른 프로젝트에서도 쓸수있게 만든다.
컴포넌트에서 데이터 로드에 대한 역할을 제거해라!
기능을 효율적으로 묶고, 아키텍처를 최대한 활용해라!
데이터 로드 및 아키텍처에 대한 의존도를 낮추고
필요하다면 props로 주입 받아라
46. 순수함수란? (Pure Function)
인풋이 같으면 항상 같은 값을 반환한다.
그러니까 주어진 값으로 계산만 해라!
쉬운말로 딴짓 하지마!
그래서 리듀서의 역할은 매우 단순하다
,
O NT
R : !
I A C
47. 단순하지만 굉장히 어려운 이뮤터빌리티!
리듀서의 상태 변경 로직은
단순한 삼중등호를 이용한다.
즉, 상태 반환시
항상 새로운 상태 레퍼랜스를 반환해야한다.
기존 상태에 값만 변경하는 행위는
객체의 참조를 변경시키지 않는다
const initialState = { x:1, y: 2 };
function reducer(state=initialState, action) {
state.x = 3;
state.y = action.payload;
return state;
}
:& A
3 : : &
,
48. 단순하기 때문에 개발자의 책임도 많아진다.
변경을 알리는 로직은 어떤 값이 변경 됐는지
구분하지 않고 단순히 상태가 변경 됐을 때
모두 구독자에게 알려준다.
Note that selectorFactory is responsible for all caching/memoization of
inbound and outbound props. Do not use connectAdvanced directly
without memoizing results between calls to your selector, otherwise the
Connect component will re-render on every state or props change.
function mapStateToProps( state: Object ) {
// 이곳에서 캐싱/메모이제이션을 처리해서 넘겨야한다.
const testState = state.get(‘test');
const testValue = reselectValue(testState);
// 결국 이곳에서 반환되는 값들은 React의 shouldComponentUpdate 사이클을 타게 된다.
return {
test: testValue,
};
}
export default connect(mapStateToProps)(ReactComponent);
&
Redux 코드를 까보면 나오는 주석!
아! -__-;;;; 얘들은 이런 중요한 얘기를 문서가
아닌 코드에 심어 놓는구나…
49. 브라우저(글로벌) 영역
애플리케이션 영역
리덕스 영역
Middleware Control Flow
. E A A E A I - E /
l pSh
/
E E
EC
. )/ )/
pSh MS
( A A
( C A
EC AA
E
E E
/) .
iMS
E
sRf T rk
Pao f
E
Lj
. E A
( A A
C CE
gc
E C CE
/
e
사용자
A
(
Pao
/
e / OP V
EC A
A A
,
Lj
pSh
E EE A
mn
d
bU
A
Lj
EC A
Redux 아키텍처의 이해, Reducer 요기!
54. 액션 생성자를 오해하게 만드는 예제
export function requestUserLocation(){
return (dispatch, getState) => {
return dispatch({
type: 'USER_LOCATION_REQUEST'
});
}
}
redux-thunk 를 이용한 샘플을 따라하면서 잘못 사용하고 있다.
테스트하기 어렵다.
dispatch를 직접 실행하면서 본래 목적과 혼용되기 쉽다.
코드만 보면 dispatch가 갑자기 어디선가 주입된다.
왜!
안좋아?
56. 액션 생성자를 사용하는 올바른 예!
export function addComment( noteId, values ) {
if( !values ) { return { type: types.NO_VALUE } }
values.author = Parse.User.current();
values.referrerId = noteId;
return {
type : types.PARSE_SERVER,
payload: {
objectName: 'Comment',
method : 'POST',
params : values,
},
meta : {
prefix: 'COMMENT_ADD',
noteId,
schema: Schemas.COMMENT,
},
};
}
왜!
좋아?
테스트하기 쉽다.
단순하다.
57. 브라우저(글로벌) 영역
애플리케이션 영역
리덕스 영역
Middleware Control Flow
. E A A E A I - E /
l pSh
/
E E
EC
. )/ )/
pSh MS
( A A
( C A
EC AA
E
E E
/) .
iMS
E
sRf T rk
Pao f
E
Lj
. E A
( A A
C CE
gc
E C CE
/
e
사용자
A
(
Pao
/
e / OP V
EC A
A A
,
Lj
pSh
E EE A
mn
d
bU
A
Lj
EC A
Redux 아키텍처의 이해, 액션 생성자
요기!
59. 미들웨어는 순차적으로 실행이 되므로 상황에 따라서 마지막 미들웨어는 실행되지 않을수도 있다.
compose(
//applyMiddleware(require('redux-immutable-state-invariant')()),
applyMiddleware(thunk, parse),
applyMiddleware(sagaMiddleware),
//applyMiddleware(createLogger()),
applyMiddleware(redirectMiddleware),
window.devToolsExtension ? window.devToolsExtension() : f => f,
),
여기서 정의된 순서로 실행된다.
Middleware
A / ) / / / / (A
/
/ /
/
(/ A ) /
미들웨어
Thunk
미들웨어
Saga
미들웨어
Logger
미들웨어
Custom..
60. 액션을 처음으로 다시 되돌릴수도 있다.
액션은 중간에 사라지기도 한다.
미들웨어를 통과한 마지막 액션은
항상 순수한 액션 객체여야 한다.
다음 미들웨어에 액션을 넘기면서 진행된다.
새로운 액션을 만들수도 있다.
미들웨어 안에서 변형되는 다양한 액션들
import { browserHistory } from 'react-router';
export default store => next => action => {
if ( action.redirect ) {
setTimeout(() => {
browserHistory.replace(action.redirect.pathname);
}, 0);
}
next(action);
}
action.redirect 값이 있으면
URL을 변경하는 간단한 미들웨어
미들웨어
Thunk
미들웨어
Saga
미들웨어
Custom) . ) .
. ) (
61. 미들웨어 안에서 다양하게 응용되는 상황들
N P I
.
미들웨어
Thunk
미들웨어
Saga
미들웨어
Custom. .
. (
)
A ) R
P I
.
A P I R a R
P RS
RTOC
62. 브라우저(글로벌) 영역
애플리케이션 영역
리덕스 영역
Middleware Control Flow
. E A A E A I - E /
l pSh
/
E E
EC
. )/ )/
pSh MS
( A A
( C A
EC AA
E
E E
/) .
iMS
E
sRf T rk
Pao f
E
Lj
. E A
( A A
C CE
gc
E C CE
/
e
사용자
A
(
Pao
/
e / OP V
EC A
A A
,
Lj
pSh
E EE A
mn
d
bU
A
Lj
EC A
Redux 아키텍처의 이해, 미들웨어
요~오기!
74. 생각해볼수 있는 전략 4가지
1. 라우터와 리덕스를 동기화 시킨다.
- SAVE_NOTE_SUCCESS 액션을 라우팅 리듀서가 받아서 상태를 바꾸면 알아서 라우더가 변경된다
- 라우팅 리듀서에 매번 액션을 정의 하기가 좀 거시기해…
2. 라우팅 리듀서가 모든 메시지를 모니터하고 있다가
액션에 redirect payload가 있다면 URL을 변경한다.
- 하지만 미들웨어가 모든 메시지를 모니터하는게 좀 걸려..
3. 특정 비동기 액션이 끝나면 명시적으로 라우팅 액션을 실행한다.
- Saga 라면 이 부분을 좀더 쉽게 할수있겠지
- 미들웨어에서 비동기를 처리하더라도 콜백을 받을수 있기 때문에 쉽게 라우팅 액션 처리가 가능하다.
4. 2번과 3번을 적절히 조합.
- 공통 액션 처리에 대한 공통 라우팅 전략으로 적합하다.
- { type: ‘SAVE_NOTE’, payload: { content }, redirect: { pathname: ‘/guide’ } }
75. 그밖에, 아키텍처에 영향을 주는 결정
스펙 변경
모듈 업데이트 ( webpack, react-router v3 to v4 )
배포 환경의 변화
immutablejs 도입
Flow type checker / typescript 도입
ServerSide Rendering
클라우드 API / GraphQL 도입
Rx / MobiX 등 근간을 이루는 아키텍처 패러다임의 변화