상태관리 라이브러리 라는 이름으로도 불린다.
useState를 이용함에 있어서 불편한 부분들이 존재했다.
dispatch가 action을 store에 전달,
store는 action 객체에 있는 타입에 따라,
state를 변경하는 작업을 함.,
action객체
switch문으로 되어있고
type에 따라 변함,.
useSelector , useDispatch
import { useDispatch, useSelector } from "react-redux"
import './App.css';
import { minusOne, plusOne } from "./redux/modules/counter";
function App() {
const counter = useSelector((state) => {
return state.counter;
})
const dispatch = useDispatch();
return (
<>
<div>
현재 카운트 : {counter.number}
</div>
<button onClick={() => {
dispatch(plusOne())
}}>++</button>
<button onClick={() => {
dispatch(minusOne())
}}>--</button>
</>
)
}
export default App
const counter = (state = initialState, action) => {
switch (action.type) {
case "PLUS_ONE":
return { number: state.number + 1 };
case "MINUS_ONE":
return { number: state.number - 1 };
default:
return state;
}
};
export default counter;
case에 입력한 문자열은 오류가 발생 할 수 있다 (human error)
Redux Action Value Creator
// 초기 상태값 initialState라는 시멘틱한 이름
// 원래 값을 const [counter , setCounter] = useState(0) 적었던 부분이다.
const initialState = {
number: 0,
};
// action value
// action creator를 쓰는 시점에서 이 부분은 내부에서만 사용하기 떄문에 export를 할 이유가 없다.
export const PLUS_ONE = "counter/PLUS_ONE";
export const MINUS_ONE = "counter/MINUS_ONE";
//action creator : action value를 return하는 함수
export const plusOne = () => {
return {
type: PLUS_ONE,
};
};
export const minusOne = () => {
return {
type: MINUS_ONE,
};
};
//리듀서 : 'state의 변화를 일으키는' 함수
// (1) state를 action의 type에 따라 변경하는 함수
// input(인자)으로 state와 action을 받는다.
const counter = (state = initialState, action) => {
switch (action.type) {
case PLUS_ONE:
return { number: state.number + 1 };
case MINUS_ONE:
return { number: state.number - 1 };
default:
return state;
}
};
export default counter;
따라서 다음과 같이 상단에 상수로 선언,
counter 내부에 삽입, 그리고 export해주고 해당하는 dispatch 또한 export해준다.
action.type
payload
범위를 지정해 주는 것과 같다. payload를 설정해줄 경우 인자로 payload를 받는 것을 명시해줘야 한다.
export const plusN = (payload) => {
return {
type: PLUS_N,
payload: payload,
};
};
export const minusN = (payload) => {
return {
type: MINUS_N,
payload: payload,
};
};
//기존의 action creator에 payload key값을 추가한 type을 추가해주었다.
...
const counter = (state = initialState, action) => {
switch (action.type) {
case PLUS_ONE:
return { number: state.number + 1 };
case MINUS_ONE:
return { number: state.number - 1 };
case PLUS_N:
return { number: state.number + action.payload };
case MINUS_N:
return { number: state.number - action.payload };
default:
return state;
}
};
// action에도 payload를 추가해주었다.
import { plusN, minusN } from "./redux/modules/counter";
// 상단에 plusN minusN을 추가해주고
function App() {
const [number, setNumber] = useState(0);
//useState를 통해 변동시킬 값을 설정해준다.
const counter = useSelector((state) => {
return state.counter;
})
useEffect(() => {
console.log('number 값', number)
}, [number])
const dispatch = useDispatch();
return (
<>
<div>
현재 카운트 : {counter.number}
</div>
<div
>
<input type="number"
value={number}
onChange={(e) =>
setNumber(e.target.value)} />
</div>
<button onClick={() => {
dispatch(plusN(number))
}}>++</button>
<button onClick={() => {
dispatch(minusN(number))
}}>--</button>
</>
)
}
// plusN 과 minusN는 인자로 payload에 해당하는 number를 받는다.
주의할 부분이 있는데, 현재 setNumber 부분에 onChange로 변경되는 부분이 문자열로 인식하게된다.
따라서 ‘+’ 를 추가해준다
<div
>
<input type="number"
value={number}
onChange={(e) =>
setNumber(+e.target.value)} />
//setNumber에 + 추가했음
</div>
아마도, 이 부분이 value값으로 덮어씌워지는 것이 아닌, 더해지는 형식으로 변환 할 수 있게 된 것 같다. ( 질문요망 )
또 setNumber(+ e.target.value)는 다음과 같이 불러 올 수도 있다.
onChange={(e) => {
const { value } = e.target
setNumber( +value);
}} />
이렇게 할당하면 value를 구조분해 할당으로 불러오는 것이므로 간결하게 표현 할 수 있고,
만약 가져온 value의 이름을 다른 이름으로 할당하고 싶다면
const {value : 원하는 이름} = e.target
setNumber( + value);
}} />
만약 onChange의 이벤트 핸들러를 외부에 작성 후 불러온다면 다음과 같이 작성 할 수 있다
const changeEventHandler = (e) =>{
const {value} = e.target
setNumber( + value );
...
return
...
<input type="number"
value={number}
onChange={changeEventHandler } />
이렇게 할당하게 되면 훨씬 더 간결한 함수의 표현이 될 수 있다.
'React' 카테고리의 다른 글
2024.1.31 기록 ( props drilling) (0) | 2024.01.31 |
---|---|
2024.1.29 기록 (Link 컴포넌트와 useNavigate의 차이) (0) | 2024.01.29 |
2024.1.25 기록 ( 최적화를 위한 hook) (1) | 2024.01.25 |
2024.1.24 기록 (JavaScript closure 와 React useState) (1) | 2024.01.24 |
2024.1.23 기록 (React fragment와 useState) (1) | 2024.01.23 |