Redux란 웹 어플리케이션의 상태 관리를 위한 오픈소스다.
Redux - A predictable state container for JavaScript apps. | Redux
A predictable state container for JavaScript apps.
redux.js.org
리액트에선 컴포넌트간 property 전달을 줄이기 위해 사용된다.
React Redux | React Redux
Official React bindings for Redux
react-redux.js.org
Redux 동작 방식
Redux는 상태 관리를 위해 사용된다. 즉 상태를 관리하며, 업데이트 하고 상태에 접근하는데 사용되는 프레임워크다.
Redux는 다음과 같은 방식으로 진행된다.
앱에서는 이벤트를 발생시킨다.
이벤트는 특정 action을 dispatch를 통해 reducer로 전달시킨다.
reducer는 자신에게 정의된 룰에 의해 state를 업데이트 시킨다.
업데이트 시켜진 state는 자신을 구독중인 컴포넌트를 업데이트 시킨다.
Redux 설치
redux를 react에서 사용하기 위해선 다음 두개의 모듈을 설치해야 한다.
npm install redux react-redux
Redux 적용
Redux를 적용시키기 위한 방법이다.
1. redux를 적용시키기 위한 최상위 컴포넌트를 <Provider> 태그로 감싼다.
이 태그로 감싸진 컴포넌트들은 모두 Redux를 사용할 수 있다.
src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { Provider } from 'react-redux';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Provider store={store}>
<App />
</Provider>
);
reportWebVitals();
2. 초기 상태와 reducer를 생성해, 해당 reducer로 store를 만든다.
src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
const initState = {
n: 1
}
function reducer(currentState=initState, action){
const newState = {...currentState}
switch(action.type){
case "ADD":
newState.n++
console.log(action.data);
break;
}
return newState
}
const store = createStore(reducer)
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Provider store={store}>
<App />
</Provider>
);
reportWebVitals();
이번 예제에서는 state는 n이라는 변수를 하나 가지고, ADD라는 action을 통해 n을 +1 하게된다.
3. state를 사용하려는 컴포넌트로 가 useSelector로 구독한다.
src/Counter.js
import React, {useState, useEffect} from "react";
import styled from "styled-components";
import {useSelector} from 'react-redux';
const Div = styled.div`
color:${props => props.color};
&:hover {
color:cyan;
}
`
function Counter() {
const n = useSelector((state) => {
return state.n;
})
const [a, set_a] = useState(0);
return (
<>
<Div color="red">{n}</Div>
<button
onClick ={() => {
}}
>up</button>
</>
)
}
export default Counter;
13~15줄에서 store의 n이라는 state를 구독한다.
4. 이벤트를 통해 dispatch 한다
src/Counter.js
import React, {useState, useEffect} from "react";
import styled from "styled-components";
import {useSelector, useDispatch} from 'react-redux';
const Div = styled.div`
color:${props => props.color};
&:hover {
color:cyan;
}
`
function Counter() {
const n = useSelector((state) => {
return state.n;
})
const dispatch = useDispatch();
const [a, set_a] = useState(0);
return (
<>
<Div color="red">{n}</Div>
<button
onClick ={() => {
dispatch({
type: "ADD",
data: {
id: 0,
text: "sample"
}
})
}}
>up</button>
</>
)
}
export default Counter;
버튼을 클릭하게 되면, type: "ADD"인 action이 디스패치 되게 된다.
실행
이제 버튼을 누르게 되면 값이 올라가게 되고 콘솔창에 action으로 넘기게된 data값에 대한 정보가 나오게 된다.
실행 코드
src/Counter.js
import React, {useState} from "react";
import styled from "styled-components";
import {useSelector, useDispatch} from 'react-redux';
const Div = styled.div`
color:${props => props.color};
&:hover {
color:cyan;
}
`
function Counter() {
const n = useSelector((state) => {
return state.n;
})
const dispatch = useDispatch();
return (
<>
<Div color="red">{n}</Div>
<button
onClick ={() => {
dispatch({
type: "ADD",
data: {
id: 0,
text: "sample"
}
})
}}
>up</button>
</>
)
}
export default Counter;
src/App.js
import React from "react"
import Counter from './Counter';
function App() {
return (
<div>
<Counter/>
</div>
);
}
export default App;
src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
const initState = {
n: 1
}
function reducer(currentState=initState, action){
const newState = {...currentState}
switch(action.type){
case "ADD":
newState.n++
console.log(action.data);
break;
}
return newState
}
const store = createStore(reducer)
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Provider store={store}>
<App />
</Provider>
);
reportWebVitals();