redux 기본 용어
1. action
상태에 변화가 필요하다면 action을 일으켜야한다. action은 객체로 표현되며 type 필드를 필수로 가져야한다.
type에는 action을 설명하는 string값이 들어가야하며, payload에는 추가할 다른 필드를 작성한다.
{
type: 'ADD',
payload: {
id: 1,
text: 'object'
}
}
2. action creater, createAction
action creater : 액션객체를 만들어주는 함수
createAction : 직접 객체를 만들지 않아도 되는 함수
import { createAction, handleActions } from 'redux-actions'
const CHANGE_USER = 'user/CHANGE_USER';
function action_Creater(data){return{type:'ADD',data}}
action_Creater = (data) => {return{type:'ADD',data,}}
action_Creater = data => ({type:'ADD',data})
action_Creater = creatAction(ADD, data => data)
3. reducer
변화를 일으키는 것-이란 뜻.
현재 상태와 액션객체를 받아, 필요하다면 새로운 상태를 리턴하는 함수.
액션 유형을 기반으로 이벤트를 처리하는 이벤트 리스너.
const initialState = { counter: 1 }
function reducer(state=initialState, action){
switch(action.type){
case INCREMENT:
return{
counter: state.counter + 1,
}
default:
return state
}
}
4. store
상태가 들어있는 store. 하나의 프로젝트에는 하나의 스토어만 존재한다.
5. dispatch
store의 내장함수 중 하나. 액션 객체를 넘겨줘서 상태를 업데이트하는 유일한 방법이다.
인자값으로 받은 함수를 계속 리턴해 상태를 계속 업데이트한다. 일종의 이벤트 트리거.
6. Subcribe
store의 내장함수 중 하나. 이벤트를 등록만!한다.
리스너 함수를 파라미터로 넣어 호출하면 상태가 업데이트 될때마다 호출된다.
일종의 이벤트 리스너.
const listender = () => {
console.log('상태를 업데이트')
}
const unsubscribe = store.subscribe(listener)
unsubscribe() // 추후 구독을 비활성화할 때 함수를 호출
7. Selector
일반적인 리덕스에서 상태값을 가져올때 store의 내장함수인 getState를 사용하지만,
react-redux에서 상태값을 가져올때 사용한다.
redux의 세가지 원칙
1. Single source of truth
하나의 어플리케이션에는 단 하나의 store가 존재한다.
이것으로 어플리케이션의 디버깅이 쉬워지고, 서버와의 직렬화가 될 수 있고, 쉽게 클라이언트에서 데이터를 받아들여올 수 있게된다.
2. State is read-only
state를 변화시키는 방법은 오직 action을 일으키는 것이다.
이것으로 상태를 변화시키는 의도를 정확하게 표현할 수 있고, 상태 변경에 대한 용이해진다.
3. Changes are made with pure functions
변화를 일으키는 reducer 함수는 순수한 함수여야한다.
순수한 함수란 다음의 조건을 만족한다.
- reducer 함수는 이전 상태와 액션 객체를 파라미터로 받는다
- 파라미터 외의 값에는 의존하면 안된다
- 이전 상태는 절대로 건드리지 않고, 변화를 준 새로운 상태 객체를 만들어서 반환한다
- 똑같은 파라미터로 호출된 리듀서 함수는 언제나 똑같은 결과 값을 반환해야한다.
redux 상태 변화의 흐름
초기상태
- 먼저 root reducer 함수를 사용하여 만들어진 redux store가 있다.
- store은 root reducer를 한번 호출하고 return 값을 초기 상태로 저장한다.
- UI가 처음 렌더링될때, UI 컴포넌트는 redux store의 상태에 접근해 그것을 렌더링애 활용한다.
- redux store의 상태는 후에 상태의 변화가 업데이트 되는 것을 subscribe한다.
업데이트 (순서)
1. 유저가 버튼을 클릭
2. 앱은 유저의 행동에 맞는 dispatch를 실행해 action을 일으킴
3. store은 이전 상태와 현재 action으로 reducer 함수를 실행하고 그 리턴값을 새로운 상태로 저장한다.
4. store은 store을 구독하고 있던 UI들에게 업데이트 되었다고 알려준다.
5. store의 데이터가 필요한 각각의 UI들은 필요한 상태가 업데이트 되었는지 확인한다.
6. 데이터가 변경된 각 구성요소는 새 데이터로 다시 렌더링하므로 화면에 표시되는 내용을 업데이트 할 수 있다.
react-redux 4인방
import {Provider, useSelector, useDispatch, connect} from 'react-redux'
Provider
사용할 컴포넌트를 감싸는 기능
state를 어떤 컴포넌트들에게 제공할 것인가-를 결정짓는 바깥쪽 울타리.
선언한 store이 Provider store = { store }과 같다.
const initialState = {}
function rootReducer(state = initialState, action){ ... }
const store = createStore(rootReducer)
export default function App(){
return(
<Provider store={store}>
<Left1></Left1>
<Right />
</Provider>
)
}
useSelector( function )
state를 부모-자녀사이를 유선으로 줄줄줄 연결하지 않고도 무선으로 띱!!하고 연결할 수 있도록 만들어줌
사용할 state를 선택함. 이게 왜 가능하냐?? reducer가 전역적으로 state를 저장하고 있었기 때문!
그러니까 모든 state를 끌어다가 사용할 수 있게 모아놓는게 useSelector의 기능임.
function Left(props){
const number = useSelector(state => state.number);
return(
<div>
<h1> Hello : {number} </h1>
</div>
)
}
useDispatch
state값을 변경
function rootReducer(currentState, action){
if(currentState === undefinded){
return {
number: 1,
}
}
const newState = {...currentState};
if(action.type === 'PLUS'){
return(
newState.number++;
)
}
return newState;
}
function Right(props){
const dispatch = useDispatch();
return(
<div>
<h1>Right:</h1>
<input type="button" value="" onClick={()=>{
dispatch({type:'PLUS'})
}}
></input>
</div>
)
}
connect의 기본함수 두가지
React컴포넌트와 Redux store을 연결해주는 역할을 함
- mapStateToProps() : Redux state를 React 컴포넌트의 props와 연결
- mapDispatchToProps() : Redux action를 React 컴포넌트의 props와 연결
공부하는데 너무 많은 도움이 되었던 블로그
( https://usonkrap.github.io/2018/12/15/React-Redux-Tutorial-for-Beginners.html )
'프로그래밍 > react' 카테고리의 다른 글
Next에 Emotion 사용하기 (0) | 2022.08.10 |
---|---|
Next에 Chakra 설치와 사용법 (0) | 2022.07.31 |
[220510] Next.js란? (0) | 2022.05.13 |
[220506] 미들웨어) redux-saga (0) | 2022.05.11 |
[220504] 미들웨어) redux-thunk (0) | 2022.05.10 |
댓글