리엑트 리덕스 설치 명령어
npm install redux react-redux
yarn add redux react-redux
store 생성
import { createStore } from 'redux';
const store = createStore(reducer)
store를 생성할 때 반드시 주입해 주어야하는것은 Reducer 이다.
reducer의 역할은 store안에있는 state를 어떻게 바꿀것인가를 결정하는 역할을 한다.
reducer는 두개의 파라미터를 받는다
// currentState = 현재 state 상태값
// action state를 어떻게 바꿀것이지에 대한 요청
// 그렇게 받은 값을 return 시켜주면 새로운 state값이 된다.
// 이때 redux에서는 각각의 state들에 대해서 불변의 법칙을 지켜야하는데
const reducer = (currentState, action) => {
// state의 복제본을 만들어서 사용하여 불변의 법칙을 지켜야 한다.
// 복제본을 수정하면 불변성을 유지할 수 있다.
const newState = { ...currentState }
// 그렇게 변화 시킨 state를 return 한다.
return newState
}
// 혹은 currentState가 undefined 일때
// state의 값이 정해져 있지 않았으므로
// 기본 state값을 return 하는것으로 기본값을 정해줄 수 있다.
const reducer = (currentState, action) => {
if(currentState === undefined) {
return {
number: 1
}
}
}
provider, useSelection, useDispatch, connect 사용
Provider = 컴포넌트
useSelector = 어떤 state값을 사용하고 싶은지 선택하는 것
useDispatch = state 를 변경시킬때 사용
connect = 재사용
import { Provider, useSelector, useDispatch, connect } from 'react-redux';
Provider 는 redux의 state를 어떤 컴포넌트에 제공할 것인가, 가장 바깥 울타리를 정하는 역할을 한다.
// component1.js
const Component = () => {
return(
<div>
// 사용할 컴포넌트를 Provider로 감싼다.
// Provider는 프롭으로 store가 반드시 와야한다.
// store속성 값으로는 위에서 선언했던 store가 오면 된다.
<Provider store={store}>
<Component1 />
</Provider>
// 그러면 위의 컴포넌트들은 store 가 사용 가능하도록 변한다.
</div>
)
}
export default Component1
// componrnt2.js
const Component1 = () => {
return(
<div>
<h1>Left1: </h1>
<Component2 />
</div>
)
}
export default Component2
// right1.js
const Right1 = () => {
return (
<button>
+
</button>
)
}
export default Right1
// right2.js
const Right2 = () => {
return (
<button>
+
</button>
)
}
export default Right2
그럼 위에서 선언한 state number를 보여줄려면 어떻게 해야하는가?
const reducer = (currentState, action) => {
if(currentState === undefined) {
return {
number: 1
}
}
const newState = { ...currentState }
return newState;
}
이때 사용하는것이 useSelector이다.
// component2.js
const Component2 = () => {
// useSelectore은 함수를 인자로 받는다.
const number = useSelector();
// useSelector의 인자로 들어갈 함수의 매개변수로는 state가 들어간다.
// 해당 state값중 어떤 값을 사용할 것인지 적으면된다.
const function = (state) => {
return state.number
}
return (
<div>
<h1>Left1: </h1>
<Component2 />
</div>
)
}
export default Component2;
// component2.js
const Component2 = () => {
// useSelectore은 함수를 인자로 받는다.
const number = useSelector(function);
// useSelector의 인자로 들어갈 함수의 매개변수로는 state가 들어간다.
// 해당 state값중 어떤 값을 사용할 것인지 적으면된다.
const function = (state) => {
return state.number
}
// 위의 코드를 간단하게 작성하면
const number = useSelector(state => state.number)
// 와 같이 사용할 수 있다.
return (
<div>
// 위에서 선언한 number를 아래와 같이 입력하게 되면
// sotre에 저장되어있는 number가 보여지게 된다.
<h1>Left1: {number}</h1>
<Component2 />
</div>
)
}
export default Component2;
그렇담 위의 store에 저장된 state를 변경하기 위해서는
state를 변경하는 useDispatch를 사용하면 된다.
// right2.js
const Right2 = () => {
// 가져온 useDispatch() 를 변수에 선언하고
const dispatch = useDispatch();
return (
<button
// state를 변경할 이벤트 함수에 dispatch 를 사용한다.
// dispatch()의 인자로 { type: "PLUS" } 를 입력해주게되면
// 이 뜻은 PLUS라는 Action을 전달하게된다.
// 그렇게 되면 reducer가 호출되게 되는데
onClick={() => dispatch({ type: 'PLUS' })}
>
+
</button>
)
}
export default Right2
// 호출된 reduce
const reducer = (currentState, action) => {
if(currentState === undefined) {
return {
number: 1
}
}
const newState = { ...currentState }
// 조건문으로 action의 타입이 'PLUS' 일때
// state가 변경되는 식을 작성하게되면 버튼을 클릭 했을때
// state가 변경되게 된다.
if(action.type === 'PLUS') {
newState.number++;
}
return newState;
}