애플리케이션 규모가 커질 수록 필요없는 data flow가 생기고 상태 관리가 어려워짐
"Redux is a predictable state container for JavaScript apps."
다양한 JavaScript applications에서 state를 관리하기 위해 사용될 수 있다.
상태 예측 가능하게 만들어준다. (reducer는 순수함수를 사용하기 때문)
유지보수
디버깅 유리(action과 state log기록 시)
테스트 붙이기 쉽다(순수함수를 사용하기 때문)
Flux는 Facebook에서 클라이언트-사이드 웹 어플리케이션을 만들기 위해 사용하는 어플리케이션 아키텍쳐다. 단방향 데이터 흐름을 활용해 뷰 컴포넌트를 구성하는 React를 보완하는 역할을 한다
An Action would encapsulate all the necessary information to update the state in the Store(s). The Dispatcher on the way delegates the Actions to the Store(s). Then, the new state would be propagated from the Store(s) to the View to update them.
Dispatcher, Stores, Views(React 컴포넌트)가 핵심 역활을 한다.
리덕스는 Flux의 몇 가지 중요한 특성에 영감을 받아 개발되었다. Flux와 달리 리덕스는 dispatcher라는 개념이 존재하지 않는다. 그리고 다수의 store도 존재하지 않는다. 대신 리덕스는 하나의 root에 하나의 store만이 존재하고, 순수함수(pure functions)에 의존하는데, 이 순수 함수는 이것들을 관리하는 추가적인 entity 없이도 조합하기 쉽다 .
-> 문자열 값 가진 type 키 (주로 action type으로 많이 씀) + 부가적인 아무 값이나 다 가질 수 있는 payload로 이루어진다
{
type: 'TODO_ADD',
todo: { id: '0', name: 'learn redux', completed: false },
}
pure function, no side-effects, input을 받아 output을 내보내는 작업만을 수행한다.
Immutability(불변성)
Reducer 함수 작성할 때 주의해야 할 점: Redux의 state 업데이트는 immutable한 방식으로 변경해야 한다--> Redux의 장점 중 하나인 변경된 state를 로그로 남기기 위해
shallow equality checking
주소값이 바뀌어야 한다
주소값이 변경되어야 바뀐 state 인식- 재렌더링
=>성능, 복잡도 단축
Object.assign,concat 등을 통해 새로운 객체를 만들어 리턴
여러가지 action 들을 받아 그에 맞는 리턴값을 만들기 위해 주로 switch문 유용
브라우저상 이벤트-> dispatch의 전달인자로 action 객체 담음-> reducer에 전달(reducer는 action 객체 타입따라 다른 동작 수행)-> 동작 수행결과 새로운 state 반환 됨
방법2가지
connect parameter를 통해 mapStateToProps, mapDispatchToProps 등 의 메소드를 이용하는 방법
Redux hooks를 이용
Allows you to extract data from the Redux store state, using a selector function.
먼저 useSelector()는 컴포넌트와 state를 연결하는 메소드. 컴포넌트에서 useSelector 메소드를 통해 store의 state에 접근할 수 있다
useSelector의 전달인자로는 콜백 함수를 받으며 콜백 함수의 전달인자로는 state 값이 들어감
import React from 'react'
import { useSelector } from 'react-redux'
export const CounterComponent = () => {
const counter = useSelector((state) => state.counter)
return <div>{counter}</div>
}
useDispatch()는 Action 객체를 Reducer로 전달해주는 메소드. 클릭 등 Action이 일어나는 컴포넌트
import React from 'react'
import { useDispatch } from 'react-redux'
export const CounterComponent = ({ value }) => {
const dispatch = useDispatch()
return (
<div>
<span>{value}</span>
<button onClick={() => dispatch({ type: 'increment-counter' })}>
Increment counter
</button>
</div>
)
}
A thunk is a function that wraps an expression to delay its evaluation.
// calculation of 1 + 2 is immediate
// x === 3
let x = 1 + 2;
// calculation of 1 + 2 is delayed
// foo can be called later to perform the calculation
// foo is a thunk!
let foo = () => 1 + 2;
With a plain basic Redux store, you can only do simple synchronous updates by dispatching an action. Middleware extends the store's abilities, and lets you write async logic that interacts with the store.
Thunks are the recommended middleware for basic Redux side effects logic, including complex synchronous logic that needs access to the store, and simple async logic like AJAX requests.
Redux Thunk middleware allows you to write action creators that return a function instead of an action.
The thunk can be used to delay the dispatch of an action, or to dispatch only if a certain condition is met
리덕스를 사용하는 어플리케이션에서 비동기 작업을 처리 할 때 가장 기본적인 방법으로는 redux-thunk 라는 미들웨어를 사용한다.
redux thunk middleware 사용시 액션 생성자를 쓸 때 액션 대신 함수를 리턴시킬 수 있다.
액션 dispatch 메서드를 딜레이시키거나 특정 조건 하에서 작동하도록 할 수 있다.(비동기 작업)