Publish to my blog (weekly)
-
Higher-Order Components - React
- Concretely, a higher-order component is a function that takes a component and returns a new component.
- Whereas a component transforms props into UI, a higher-order component transforms a component into another component.
- HOCs are common in third-party React libraries, such as Redux's
connect
and Relay'screateContainer
. - // This function takes a component... function withSubscription(WrappedComponent, selectData) { // ...and returns another component... return class extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); this.state = { data: selectData(DataSource, props) }; } componentDidMount() { // ... that takes care of the subscription... DataSource.addChangeListener(this.handleChange); } componentWillUnmount() { DataSource.removeChangeListener(this.handleChange); } handleChange() { this.setState({ data: selectData(DataSource, this.props) }); } render() { // ... and renders the wrapped component with the fresh data! // Notice that we pass through any additional props return <WrappedComponent data={this.state.data} {...this.props} />; } }; }
- Rather, an HOC composes the original component by wrapping it in a container component. An HOC is a pure function with zero side-effects.
-
-
react-redux/api.md at master · reactjs/react-redux
- If this argument is specified, the new component will subscribe to Redux store updates.
- The results of
mapStateToProps
must be a plain object, which will be merged into the component’s props. - This means that any time the store is updated,
mapStateToProps
will be called. - If you don't want to subscribe to store updates, pass
null
orundefined
in place ofmapStateToProps
. - it will be called with the store state as the first parameter
- taking two parameters
- the props passed to the connected component as the second parameter
- The
mapStateToProps
function takes a single argument of the entire Redux store’s state and returns an object to be passed as props. It is often called a selector. - If an object is passed, each function inside it is assumed to be a Redux action creator.
- An object with the same function names, but with every action creator wrapped into a
dispatch
call so they may be invoked directly, will be merged into the component’s props. - If a function is passed, it will be given
dispatch
as the first parameter. - It’s up to you to return an object that somehow uses
dispatch
to bind action creators in your own way. - If your
mapDispatchToProps
function is declared as taking two parameters, it will be called withdispatch
as the first parameter and the props passed to the connected component as the second parameter, - will be re-invoked whenever the connected component receives new props
- If specified, it is passed the result of
mapStateToProps()
,mapDispatchToProps()
, and the parentprops
. - Inject just
dispatch
and don't listen to store - Inject
dispatch
andtodos
- Inject
todos
and all action creators - Inject
todos
and all action creators (addTodo
,completeTodo
, ...) asactions
- Inject
todos
and a specific action creator (addTodo
) - Inject
todos
, todoActionCreators astodoActions
, and counterActionCreators ascounterActions
- Inject
todos
, and todoActionCreators and counterActionCreators together asactions
- Inject
todos
of a specific user depending on props - Inject
todos
of a specific user depending on props, and injectprops.userId
into the action - mergeProps
- mergeProps
-
-
[React.JS] 강좌 10-2편 Redux: 예제를 통해 사용해보기 | VELOPERT.LOG
- reducer를 여러개로 분리하여 작성 할 땐, 서로 직접적인 관계가 없어야 합니다.
- 이 함수의 리턴값은 특정 컴포넌트 클래스의 props 를 store의 데이터에 연결시켜주는 또 다른 함수를 리턴합니다.
- 리턴된 함수에 컴포넌트를 인수로 넣어 실행하면, 기존 컴포넌트를 수정하는게 아니라 새로운 컴포넌트를 return 합니다.
-
-
stipsan/redux-saga-sc: Provides sagas to easily dispatch redux actions over SocketCluster websockets
- You'll notice that this guide does not use the terms "server" and "client". Why? You could use this server to server, client to client, it doesn't matter. Instead you have a "sender" and a "receiver". The "sender" can
emit
something, the "receiver" listens for theemit
and may decide toemit
something back in response. The "sender" can alsorequest
something from the "receiver" requiring a response of eithersuccessType
orfailureType
-
-
Redux-Saga에서의 WebSocket(socket.io) 이벤트 처리 - Meetup : TOAST Cloud
- 소켓 채널에서 메시지를 받아 액션을 다시 Dispatch 하거나
- 다른 액션을 기다리거나
- 에러 처리 혹은 또 다른 비동기 처리 등의 많은 작업을 손쉽게 처리
-
-
Bidirectional websockets with Redux Saga – Emir Bakhtarov – Medium
- The interesting component is the “race” command. Straight after the user login the “task” begins the execution of a passed function, until the action ‘STOP_WEBSOCKET’ is fired. And this is first fired when e.g. the user pushed log out button.
- [call(externalListener, socketChannel), call(internalListener, socket)]
- The fisrt param function externalListener is the Saga channel listening to the external websocket server and processing the incoming data.
- The second one, internalListener, is a generator function listening to user commands, for example button events, dropdown changes etc. Here is an example how this listener can be implemented:
-
-
- 간결한 구문
params => {object:literal}
을 사용한 객체 리터럴 반환은 예상대로 작동하지 않음을 명심하세요: - 이는 중괄호({}) 안 코드가 일련의 문(즉
foo
는 라벨처럼 취급됩니다, 객체 리터럴 내 키가 아니라)으로 파싱(parse, 구문 분석)되기 때문입니다. - 객체 리터럴를 괄호로 감싸는 것을 기억하세요:
- ({ foo: 1 });
-
-
Using websockets with redux-saga – Pierre Maoui – Medium
- Redux-saga is mainly described as a way of dealing with side-effects (asynchronous calls and so on) performed by an application.
- Incoming actions from the store invoke a function that will dispatch later an other action back to the store.
- With websockets, we won’t rely on incoming actions but on external event sources.
- With the second pattern, we can take advantage of queueing all non-processed actions (inside requestChan).
- eventChannel is a function that takes a subscriber to initialize the external event source (it means for us to connect to the websocket server).
-
-
- a thunk is a subroutine used to inject an additional calculation into another subroutine. Thunks are primarily used to delay a calculation until it is needed, or to insert operations at the beginning or end of the other subroutine.
-
-
- State is similar to props, but it is private and fully controlled by the component.
- These methods are called "lifecycle hooks".
- Inside it, the
Clock
component schedules a UI update by callingsetState()
with an object containing the current time. - Thanks to the
setState()
call, React knows the state has changed, and callsrender()
method again to learn what should be on the screen. - React may batch multiple
setState()
calls into a single update for performance. - Because
this.props
andthis.state
may be updated asynchronously, you should not rely on their values for calculating the next state. - (prevState, props) => ({ counter: prevState.counter + props.increment })
- function(prevState, props) { return { counter: prevState.counter + props.increment }; }
-
-
- But how do you know what should be its own component? Just use the same techniques for deciding if you should create a new function or object. One such technique is the single responsibility principle, that is, a component should ideally only do one thing. If it ends up growing, it should be decomposed into smaller subcomponents.
- Now that you have your component hierarchy, it's time to implement your app. The easiest way is to build a version that takes your data model and renders the UI but has no interactivity. It's best to decouple these processes because building a static version requires a lot of typing and no thinking, and adding interactivity requires a lot of thinking and not a lot of typing. We'll see why.
-
-
Presentational and Container Components – Medium
- Presentational
- Container
- Smart
- Skinny
- Stateful
- Dumb
- Fat
- Pure
- Components
- Screens
-
- Are concerned with how things look.
- May contain both presentational and container components** inside, and usually have some DOM markup and styles of their own.
- Often allow containment via this.props.children.
- Have no dependencies on the rest of the app, such as Flux actions or stores.
- Don’t specify how the data is loaded or mutated.
- Receive data and callbacks exclusively via props.
- Rarely have their own state (when they do, it’s UI state rather than data).
- Are written as functional components unless they need state, lifecycle hooks, or performance optimizations.
- Examples: Page, Sidebar, Story, UserInfo, List.
-
- Are concerned with how things work.
- May contain both presentational and container components** inside but usually don’t have any DOM markup of their own except for some wrapping divs, and never have any styles.
- Provide the data and behavior to presentational or other container components.
- Call Flux actions and provide these as callbacks to the presentational components.
- Are often stateful, as they tend to serve as data sources.
- Are usually generated using higher order components such as connect() from React Redux, createContainer() from Relay, or Container.create() from Flux Utils, rather than written by hand.
- Examples: UserPage, FollowersSidebar, StoryContainer, FollowedUserList.
-
-
-
- 애플리케이션의 상태를 저장하고;
getState()
를 통해 상태에 접근하게 하고;dispatch(action)
를 통해 상태를 수정할 수 있게 하고;subscribe(listener)
를 통해 리스너를 등록합니다.
- let store = createStore(todoApp);
- 만약 데이터를 다루는 로직을 쪼개고 싶다면, 여러개의 스토어 대신 리듀서 조합을 사용할 수 있습니다.
- 서버에서 실행중인 Redux 애플리케이션의 상태와 일치하도록 클라이언트의 상태를 채워줄때 유용합니다.
-
createStore()
의 두번째 인수로 초기 상태를 지정 - 이 시점에서 여러분은 리듀서와 액션 생산자들을 위한 테스트를 작성할 수 있습니다. 이들은 단지 함수이기 때문에 아무것도 모조(mock)할 필요가 없습니다. 이들을 호출하고, 반환하는 것들을 검증하세요.
-
-
- 이것을 리듀서 조합이라고 부르고, 이것이 Redux 앱을 만드는 기본 패턴이 됩니다.
- 여러분이 이 형태의 함수를
Array.prototype.reduce(reducer, ?initialValue)
로 넘길 것이기 때문에 리듀서라고 부릅니다 -
- 인수들을 변경(mutate)하기;
- API 호출이나 라우팅 전환같은 사이드이펙트를 일으키기;
Date.now()
나Math.random()
같이 순수하지 않은 함수를 호출하기.
여러분이 절대로 리듀서 내에서 하지 말아야 할 것들은:
- import * as reducers from './reducers'; const todoApp = combineReducers(reducers);
-
Object.assign
에 관하여Object.assign()
은 ES6의 일부이지만, 대부분의 브라우저에서 구현되지 않았습니다. 폴리필을 사용하거나 Babel 플러그인이나_.assign()
같이 다른 라이브러리의 헬퍼를 사용해야 합니다. - Redux는
todoApp
이 위에서 했던것과 동일한 보일러플레이트 로직을 지원하는combineReducers()
라는 유틸리티를 제공합니다. 이를 이용하면todoApp
을 이렇게 재작성할 수 있습니다: -
combineReducers()
가 하는 일은 여러분의 리듀서들을 키에 따라 선택해서 잘라낸 상태들로 호출하고 그 결과를 다시 하나의 객체로 합쳐주는 함수를 만드는 것 뿐입니다 - Redux는 처음에 리듀서를
undefined
상태로 호출합니다. 그때가 초기 상태를 반환할 기회입니다:
-
-
GitHub - gaearon/redux-thunk: Thunk middleware for Redux
- The inner function receives the store methods
dispatch
andgetState
as parameters. - An action creator that returns a function to perform asynchronous dispatch:
- dispatch => { setTimeout(() => { // Yay! Can invoke sync or async actions with `dispatch` dispatch(increment()); }, 1000); };
-
An action creator that returns a function to perform conditional dispatch:
- (dispatch, getState) => { const { counter } = getState(); if (counter % 2 === 0) { return; } dispatch(increment()); };
-
-
- 리듀서는 그저 이전 상태와 액션을 받아 다음 상태를 반환하는 순수 함수
- 저장할 수 있고
- 기록을 남길 수 있고
- 시리얼라이즈할 수 있으며
- 테스트나 디버깅을 위해서 재현하
- 실행취소/다시실행(undo/redo)을 손쉽게 구현
- 빠른 개발 사이클을 위해 개발중인 애플리케이션의 상태를 저장
- 하나의 상태 트리만을 가지고 있기 때문에 디버깅에도 용이할 것
- 상태를 변화시키는 유일한 방법은 무슨 일이 벌어지는 지를 묘사하는 액션 객체를 전달하는 방법뿐입
- 액션에 의해 상태 트리가 어떻게 변화하는 지를 지정하기 위해 프로그래머는 순수 리듀서를 작성해야합니다.
- 범용적인 애플리케이션(universal application, 하나의 코드 베이스로 다양한 환경에서 실행 가능한 코드)을 만들기 쉽게 만들 수 있습니다
- 액션은 그저 평범한 객체
- 시리얼라이즈되거나(serialized)
- 수화되어(hydrated)
- [...state, { text: action.text, completed: false }];
- [ ...state.slice(0, action.index), Object.assign({}, state[action.index], { completed: true }), ...state.slice(action.index + 1) ];
- let reducer = combineReducers({ visibilityFilter, todos });
- let store = createStore(reducer);
-
-
- 각각의 액션이 전체 애플리케이션의 상태를 어떻게 변경할지 결정하는 특별한 함수인 리듀서를 작성합니다.
- 뷰 바인딩 라이브러리(예를 들어 React Redux)를 사용합니다.
- let store = createStore(counter)
-
댓글