리덕스를 사용하게 되면 어떤 시점에서 dispatch를 통해 리듀서에게 액션을 전달하게 된다.
그에 따라 리듀서는 state에 변화를 일으킨다.
하지만 추가적으로 브라우저에서 서버로 요청을 보내고 응답을 받을 때
즉 비동기적인 작업을 처리할 때를 생각해보아야 한다.
요청을 보내면 항상 100프로 응답이 성공적일 수는 없다.
실패할 수도 있다.
따라서 요청, 응답, 실패시에 따른 처리를 state에 처리해 줄 필요가 있다.
이를 통해 사용자에게 현재 어떤 상태에 있는지를 인지시킬 수 있기 떄문이다.
(여기서 인지란 비동기작업이 진행중인지? 작업완료 되었는지? 실패했는지? 를 의미 )
이때 사용할 수 있는 것이 Redux-Middleware이다.
Middleware로 액션을 디스패치 하고 리듀서에서 바로 처리하는 것이 아니라
Middle. 즉 단어의 뜻과 비슷하게 중간에 어떤 작업을 할 수 있게 해주는 것이다.
Redux Thunk
addPost라는 함수는 content라는 인자를 가진다.
프론트에서 보내고 싶은 데이터가 있다면 필요할 것이고 없다면 필요하지 않을 것이다.
함수 내에서 dispatch 사용이 가능하다.
getState로 state의 상태도 조회해 볼수가 있다.
처음에 Request를 dispatch
dummyPostsApi로 content를 집어넣은 결과값이 있다면 ADD_POST_SUCCESS를 dispatch
결과값이 없고 에러가 발생한다면 ADD_POST_FAILURE를 dispatch
export const addPost = (data) => async(dispatch) => {
dispatch({
type : ADD_POST_REQUEST,
})
try{
const result = await dummyPost(data)
dispatch({
type: ADD_POST_SUCCESS,
data : result
})
}catch(error){
dispatch({
type : ADD_POST_FAILURE
})
}
}
이제 함수 내에서 액션을 여러번 dispatch가 가능하게 되었다.
Components
import React from 'react'
import { useState } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { addPost } from '../reducer/user'
export default function Practice(){
const posts = useSelector(state => state.posts)
const dispatch = useDispatch()
const [content, setContent] = useState('')
const addPostHandler = (e) => {
console.log(content)
e.preventDefault();
dispatch(addPost({content}))
}
const onChangeContent = (e) => {
setContent(e.target.value)
}
return (
<>
<div>{posts}</div>
<form onSubmit={addPostHandler}>
<input value={content} type='text' onChange={onChangeContent}/>
<button type='submit'>
포스트작성
</button>
</form>
</>
)
}
Reducer
export const initialState ={
posts : [],
addPostLoading : false,
addPostDone : false,
addPostError : null,
}
export const ADD_POST_REQUEST = 'ADD_POST_REQUEST'
export const ADD_POST_SUCCESS = 'ADD_POST_SUCCESS'
export const ADD_POST_FAILURE = 'ADD_POST_FAILURE'
export const dummyPost = (data) => (
{
id: 1,
content : data.content
}
)
export const addPost = (data) => async(dispatch) => {
dispatch({
type : ADD_POST_REQUEST,
})
try{
const result = await dummyPost(data)
dispatch({
type: ADD_POST_SUCCESS,
data : result
})
}catch(error){
dispatch({
type : ADD_POST_FAILURE
})
}
}
const reducer = (state = initialState,action) => {
switch (action.type) {
case ADD_POST_REQUEST:
return {
...state,
addPostLoading : true,
addPostDone :false,
addPostError : null,
}
case ADD_POST_SUCCESS:
return {
...state,
addPostLoading : false,
addPostDone : true,
posts : [...state.posts, action.data]
}
case ADD_POST_FAILURE:
return{
...state,
addPostLoading : true,
addPostDone : false,
addPostError : action.data,
}
default:
return state;
}
}
export default reducer
'Redux' 카테고리의 다른 글
Redux-Toolkit (0) | 2022.03.07 |
---|
리덕스를 사용하게 되면 어떤 시점에서 dispatch를 통해 리듀서에게 액션을 전달하게 된다.
그에 따라 리듀서는 state에 변화를 일으킨다.
하지만 추가적으로 브라우저에서 서버로 요청을 보내고 응답을 받을 때
즉 비동기적인 작업을 처리할 때를 생각해보아야 한다.
요청을 보내면 항상 100프로 응답이 성공적일 수는 없다.
실패할 수도 있다.
따라서 요청, 응답, 실패시에 따른 처리를 state에 처리해 줄 필요가 있다.
이를 통해 사용자에게 현재 어떤 상태에 있는지를 인지시킬 수 있기 떄문이다.
(여기서 인지란 비동기작업이 진행중인지? 작업완료 되었는지? 실패했는지? 를 의미 )
이때 사용할 수 있는 것이 Redux-Middleware이다.
Middleware로 액션을 디스패치 하고 리듀서에서 바로 처리하는 것이 아니라
Middle. 즉 단어의 뜻과 비슷하게 중간에 어떤 작업을 할 수 있게 해주는 것이다.
Redux Thunk
addPost라는 함수는 content라는 인자를 가진다.
프론트에서 보내고 싶은 데이터가 있다면 필요할 것이고 없다면 필요하지 않을 것이다.
함수 내에서 dispatch 사용이 가능하다.
getState로 state의 상태도 조회해 볼수가 있다.
처음에 Request를 dispatch
dummyPostsApi로 content를 집어넣은 결과값이 있다면 ADD_POST_SUCCESS를 dispatch
결과값이 없고 에러가 발생한다면 ADD_POST_FAILURE를 dispatch
export const addPost = (data) => async(dispatch) => {
dispatch({
type : ADD_POST_REQUEST,
})
try{
const result = await dummyPost(data)
dispatch({
type: ADD_POST_SUCCESS,
data : result
})
}catch(error){
dispatch({
type : ADD_POST_FAILURE
})
}
}
이제 함수 내에서 액션을 여러번 dispatch가 가능하게 되었다.
Components
import React from 'react'
import { useState } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { addPost } from '../reducer/user'
export default function Practice(){
const posts = useSelector(state => state.posts)
const dispatch = useDispatch()
const [content, setContent] = useState('')
const addPostHandler = (e) => {
console.log(content)
e.preventDefault();
dispatch(addPost({content}))
}
const onChangeContent = (e) => {
setContent(e.target.value)
}
return (
<>
<div>{posts}</div>
<form onSubmit={addPostHandler}>
<input value={content} type='text' onChange={onChangeContent}/>
<button type='submit'>
포스트작성
</button>
</form>
</>
)
}
Reducer
export const initialState ={
posts : [],
addPostLoading : false,
addPostDone : false,
addPostError : null,
}
export const ADD_POST_REQUEST = 'ADD_POST_REQUEST'
export const ADD_POST_SUCCESS = 'ADD_POST_SUCCESS'
export const ADD_POST_FAILURE = 'ADD_POST_FAILURE'
export const dummyPost = (data) => (
{
id: 1,
content : data.content
}
)
export const addPost = (data) => async(dispatch) => {
dispatch({
type : ADD_POST_REQUEST,
})
try{
const result = await dummyPost(data)
dispatch({
type: ADD_POST_SUCCESS,
data : result
})
}catch(error){
dispatch({
type : ADD_POST_FAILURE
})
}
}
const reducer = (state = initialState,action) => {
switch (action.type) {
case ADD_POST_REQUEST:
return {
...state,
addPostLoading : true,
addPostDone :false,
addPostError : null,
}
case ADD_POST_SUCCESS:
return {
...state,
addPostLoading : false,
addPostDone : true,
posts : [...state.posts, action.data]
}
case ADD_POST_FAILURE:
return{
...state,
addPostLoading : true,
addPostDone : false,
addPostError : action.data,
}
default:
return state;
}
}
export default reducer
'Redux' 카테고리의 다른 글
Redux-Toolkit (0) | 2022.03.07 |
---|