상태는 크게 로컬상태 와 전역상태로 구분할 수 있습니다.
로컬상태 : 특정 컴포넌트 안에서 관리하는 상태
전역상태 : 프로덕트 전체, 혹은 여러 컴포넌트에서 관리되는 상태
로컬상태같은 경우 특정 컴포넌트 안에서 상태를 관리하기 때문에 상태로 인한 결과값을
컴포넌트를 거쳐 props로 전달하거나 상태를 변화시키는 핸들러를 props로 전달시켜
상태 끌어올리기 같은 현상이 일어납니다. 이 과정에서 코드가 굉장히 복잡해지고 컴포넌트와
상태와의 관계로 한눈에 파악하기 힘들게 됩니다. 반면 전역상태로 상태관리를 하게 되는 경우
컴포넌트 밖에 있는 전역 저장소에서 상태를 관리하고 컴포넌트는 필요할때마다 전역 저장소에 있는
상태를 불러오고 변화가 필요할때마다 전역 저장소로 새로운 상태를 보내면 됩니다.
이러한 전역저장소를 위한 여러가지 상태관리툴이 존재하는데 리덕스(redux)도 그 중 하나입니다.
스토어(Store)는 전역상태를 저장하는 저장소 역할을 합니다.
액션(Actions)은 상태를 변화시키기 위해 보내는 객체입니다. 일반적으로 동작을 나타내는 type 정보와 상태정보를 나타내는 payload 정보를 담습니다.
디스패치(Dispatch)는 액션객체를 리듀서를 통과한뒤 스토어로 보내는 역할을 합니다.
리듀서(Reducers)는 받은 액션객체를 통해 새로운 객체를 리턴합니다. 리듀서에서 상태를 변화시키는 로직은 사용자가 직접 정의합니다. 이 때 기존의 상태를 리턴하도록 로직을 짤 수도 있지만 리덕스는 상태의 불변성(immutability) 원칙을 지켜야 하기 때문에 변화가 일어나는 경우 리덕스에서 새로운 상태객체로 리턴하도록 코드를 짜야 합니다.
먼저 리덕스를 사용하기 위해서 기본 세팅을 진행합니다.
리덕스 모듈을 설치하고 가져옵니다.
그 다음 createStore(reducer)로 스토어를 생성, 리듀서를 정의합니다.
import { Provider } from 'react-redux';
import { createStore } from 'redux'; // 리덕스 세팅 준비
const 체중 = 100;
fucntion reducer(state = 체중, action){ // 리듀서는 사용자가 직접 정의합니다.
return state
}
let store = createStore(reducer) // 리덕스 저장소를 생성합니다.
ReactDOM.render(
<React,StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>,
document.getElementById('root')
);
전역 저장소에서 상태를 가져올때는 useSelector를 사용합니다.
리덕스에서는 useSelector 뿐만 아니라 getState, mapStateToProps, subcribe 등 상태를 가져올 수 있는 여러가지 방법들이 있습니다.
useSelector()의 인자로 상태를 리턴하는 함수를 작성합니다.
상태객체 전체를 가져오는 경우 (state) => state로 작성해도 되지만
일부만 가져올경우 (state) => state.counter 이런식으로 세부속성을 리턴하는것도 가능합니다.
import './App.css'
import { useSelector } from 'react-redux'
function App() {
const pureState = useSelector((state) => state);
return (
<div className="App">
<p>님의 처참한 몸무게 : {pureState}</p> // useSelector로 가져온값을 사용
</div>
);
}
export default App;
리듀서에서는 상태를 변화시키는 세부로직을 정의하도록 합니다.
일반적으로 액션객체에 type 속성을 있기 때문에 type에 따라 상태가 변화하도록 로직을 짭니다.
상태를 변화시키는 경우 새로운 객체를 리턴해야 합니다.(불변성 원칙)
import { Provider } from 'react-redux';
import { crateStore } from 'redux';
const 체중 = 100;
function reducer(state = 체중, action){
const newState;
if (action.type === '증가'){
newState = Object.assign({}, ++state)
return state
}else if(action.type === '감소'){
newState = Object.assign({}, ++state)
return state
} else {
return state
}
}
상태를 변화시킬 때는 useDispatch를 이용합니다.
useDispatch 외에도 store.dispatch, mapDispatchToProps 등이 있습니다.
import './App.css';
import { useDispatch, useSelector } from 'react-redux'
function App() {
const 꺼내온거 = useSelector((state) => state)};
const dispatch = useDispatch() // useDispatch를 호출한 값을 변수에 넣어 사용
return (
<div className="App">
<p>님의 처참한 몸무게 : {꺼내온거}</p>
<button onClick={() => { dispatch({type : '증가'}) }}>더하기</button>
</div>
)
export default app;