inflearn logo
강의

Course

Instructor

[Renewal] Creating a NodeBird SNS with React

게시물 작성 후 닉네임 변경

457

uphoon

26 asked

0

선생님 게시물을 작성하고 난 다음에 닉네임을 변경을 하면 새롭게 변경된 닉네임을 가진 게시물이 새로생기는데 이건 왜그런걸까요 ...

 

react redux express nodejs Next.js

Answer 3

0

uphoon

//saga

import { delay, all, fork, takeLatest, put, throttle, call } from "redux-saga/effects";
import {
    ADD_POST_REQUEST, ADD_POST_SUCCESS, ADD_POST_FAILURE,
    REMOVE_POST_REQUEST, REMOVE_POST_SUCCESS, REMOVE_POST_FAILURE,
    ADD_COMMENT_REQUEST, ADD_COMMENT_SUCCESS, ADD_COMMENT_FAILURE,
    LOAD_POSTS_REQUEST, LOAD_POSTS_SUCCESS, LOAD_POSTS_FAILURE,
    LIKE_POST_REQUEST, LIKE_POST_SUCCESS, LIKE_POST_FAILURE,
    UNLIKE_POST_REQUEST, UNLIKE_POST_SUCCESS, UNLIKE_POST_FAILURE
} from '../reducers/post'

import { ADD_POST_TO_ME, REMOVE_POST_TO_ME } from "../reducers/user";
import axios from "axios";
import shortId from 'shortid';

function addPostAPI(data) {
    return axios.post('/post', { content: data });
}

function* addPost(action) {
    try {
        const result = yield call(addPostAPI, action.data);
        yield console.log(result)
        yield put({
            type: ADD_POST_SUCCESS,
            data: result.data,
        });
        yield put({
            type: ADD_POST_TO_ME,
            data: result.data.id,
        });
    } catch (err) {
        console.error(err);
        yield put({
            type: ADD_POST_FAILURE,
            error: err.response.data,
        });
    }
}

function removePostAPI(data) {
    return axios.delete(`/post/${data}`)
}

function* removePost(action) {
    console.log(action.data)
    try {
        const result = yield call(removePostAPI, action.data)
        yield console.log(typeof result.data.PostId)
        yield put({
            type: REMOVE_POST_SUCCESS,
            data: result.data
        })
        yield put({
            type: REMOVE_POST_TO_ME,
            data: result.data.PostId
        })
    } catch (err) {
        yield put({
            type: REMOVE_POST_FAILURE,
            data: err.response.data
        });
    }
}

function addCommentAPI(data) {
    return axios.post(`/post/${data.postId}/comment`, data)
}

function* addComment(action) {
    try {
        const result = yield call(addCommentAPI, action.data)
        yield put({
            type: ADD_COMMENT_SUCCESS,
            data: result.data
        });
    } catch (err) {
        yield put({
            type: ADD_COMMENT_FAILURE,
            data: err.response.data
        });
    }
}

function loadPostsAPI(data) {
    return axios.get('/posts', data);
}

function* loadPosts(action) {
    try {
        const result = yield call(loadPostsAPI, action.data);
        yield console.log(result)
        yield put({
            type: LOAD_POSTS_SUCCESS,
            data: result.data,
        });
    } catch (err) {
        console.error(err);
        yield put({
            type: LOAD_POSTS_FAILURE,
            data: err.response.data,
        });
    }
}

function likePostAPI(data) {
    return axios.patch(`/post/${data}/like `, data);
}

function* likePost(action) {
    try {
        const result = yield call(likePostAPI, action.data);
        yield put({
            type: LIKE_POST_SUCCESS,
            data: result.data,
        });
    } catch (err) {
        console.error(err);
        yield put({
            type: LIKE_POST_FAILURE,
            data: err.response.data,
        });
    }
}

function UnLikePostAPI(data) {
    return axios.delete(`/post/${data}/like`);
}

function* UnLikePost(action) {
    try {
        const result = yield call(UnLikePostAPI, action.data);
        yield put({
            type: UNLIKE_POST_SUCCESS,
            data: result.data,
        });
    } catch (err) {
        console.error(err);
        yield put({
            type: UNLIKE_POST_FAILURE,
            data: err.response.data,
        });
    }
}

function* watchLoadPosts() {
    yield throttle(5000, LOAD_POSTS_REQUEST, loadPosts);
}

function* watchAddPost() {
    yield takeLatest(ADD_POST_REQUEST, addPost)
}

function* watchRemovePost() {
    yield takeLatest(REMOVE_POST_REQUEST, removePost)
}

function* watchCommentPost() {
    yield takeLatest(ADD_COMMENT_REQUEST, addComment)
}

function* watchLikePost() {
    yield takeLatest(LIKE_POST_REQUEST, likePost)
}

function* watchUnLiketPost() {
    yield takeLatest(UNLIKE_POST_REQUEST, UnLikePost)
}


export default function* postSaga() {
    yield all([
        fork(watchAddPost),
        fork(watchCommentPost),
        fork(watchRemovePost),
        fork(watchLoadPosts),
        fork(watchLikePost),
        fork(watchUnLiketPost),
    ]);
}

0

zerocho

닉네임 변경 페이지에서 어디로 갔을 때 loadUser랑 loadPosts가 되는건가요? 닉네임변경페이지에 갔다가 다른페이지에 갔을 때 mainPosts를 비우고 시작하면 될것같습니다.

0

zerocho

닉네임변경 안하고 프로필 페이지만 갔다와도 게시글이 하나더 쌓이나요?

0

uphoon

다른페이지 이동만해도 쌓입니다...

0

uphoon

제가 로직을 잘못 한 부분이 있는걸까요 아니면 뒤에 강의 더 보면 해결이 되는 부분일까요?

0

uphoon

제가 생각했을때 index에 접근하면 dispatch 가 일어나니 백엔드에 있는 게시글 그냥 가져오는거 같은데 state에만 추가 되고 백엔드에는 그대로 게시물갯수 유지되어 있고 로직은 이해가 되는데 왜저렇게 되는지 선생님은 안그러신것 같아서요

0

zerocho

로직을 잘못하신 것 같은데요. nodebird.com 보시면 전혀 그런 일이 발생하지 않습니다. hydrate같은 코드 잘못 짜신 것은 아닌가요

0

uphoon

지금 강의 완강전이고 팔로우 언팔로우 부분까지 수강중인 상태인데 아무리봐도 선생님이 팔로우 언팔로우 부분까지 짜신거 그대로 진행했는데 로직상 index.js 부분으로 다시 돌아오면

useEffect(() => {
    dispatch({
      type: LOAD_USER_REQUEST,
    });
    dispatch({
      type: LOAD_POSTS_REQUEST,
    });
  }, []);

이부분은 다시 실행되고

case LOAD_POSTS_SUCCESS:
                draft.loadPostsLoading = false;
                draft.loadPostsDone = true;
                draft.mainPosts = draft.mainPosts.concat(action.data);
                draft.hasMorePosts = draft.mainPosts.length === 10;
                break;

다시 석세스 액션 실행되서 draft.mainPosts = draft.mainPosts.concat(action.data);

get요청한 값이 다시 들어가는 형태인거 같은데 제가 여쭤보고싶은게 추후에 또 다른 내용으로 이걸 오류 잡는것인지 아니시면 그냥 제가 잘못 짠건지... 선생님은 완성하고 나신거 보여주시는거여서 이해를 하겠는데 제가 지금 진행중인 상황이라 선생님도 진행중에 이러한 애러 있으셨던건지 궁금해서요 ㅠ 완성된 형태 코드 보니까 또 바뀌는것 같아서 질문 드립니다. 계속 수정하고 뭐 때문인지 찾아보는데 안돼네요 페이지 이동하면 get요청 다시 되니 당연히 state에 쌓이는 로직인데 분명히 혹시 제가 잘못하고 있는 코드 로직 부분 봐주시면 감사하겠습니다.

https://github.com/wihyanghoon/react-nodebird

case LOAD_POSTS_SUCCESS:
                draft.loadPostsLoading = false;
                draft.loadPostsDone = true;
                draft.mainPosts = action.data;
                draft.hasMorePosts = draft.mainPosts.length === 10;
                break;

위에 로직으로 바꿔보니 페이지 이동후 다시 돌아와도 게시글이 추가가 되지는 않습니다만 선생님 로직하고는 달라서 깃허브 한번만 봐주시고 피드백 주시면 정말 감사하겠습니다.

0

zerocho

제가 말씀드린대로 hydrate 코드를 잘못 짜셨습니다.

https://github.com/ZeroCho/react-nodebird/blob/master/ch7/front/reducers/index.js#L12

이 부분은 뒤쪽 강좌에서 수정하는 부분입니다.

0

uphoon

감사합니다 ㅠㅠ

0

uphoon

//리듀서
import shortId from 'shortid';
import produce from 'immer';
import faker from 'faker';
import { LIKE_FAILURE, LIKE_REQUEST, LIKE_SUCCESS } from './user';

export const initialState = {
    mainPosts: [],
    imagePath: [],
    hasMorePosts: true,
    loadPostsLoading: false,
    loadPostsDone: false,
    loadPostsError: null,
    likeLoading: false,
    likeDone: false,
    likeError: null,
    unLikeLoading: false,
    unLikeDone: false,
    unLikeError: null,
    addPostLoadding: false,
    addPostDone: false,
    addPostErr: null,
    removePostLoadding: false,
    removePostDone: false,
    removePostErr: null,
    addCommentLoadding: false,
    addCommentDone: false,
    addCommentErr: null,
}


// export const getDemmuyPost = (number) => Array(number).fill().map(() => ({
//     id: shortId.generate(),
//     User: {
//         id: shortId.generate(),
//         nickname: faker.name.findName(),
//     },
//     content: faker.lorem.paragraph(),
//     Images: [{
//         src: faker.image.image(),
//     }],
//     Comments: [{
//         User: {
//             id: shortId.generate(),
//             nickname: faker.name.findName(),
//         },
//         content: faker.lorem.sentence(),
//     }],
// }))

export const LOAD_POSTS_REQUEST = 'LOAD_POSTS_REQUEST';
export const LOAD_POSTS_SUCCESS = 'LOAD_POSTS_SUCCESS';
export const LOAD_POSTS_FAILURE = 'LOAD_POSTS_FAILURE';

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 REMOVE_POST_REQUEST = 'REMOVE_POST_REQUEST'
export const REMOVE_POST_SUCCESS = 'REMOVE_POST_SUCCESS'
export const REMOVE_POST_FAILURE = 'REMOVE_POST_FAILURE'

export const ADD_COMMENT_REQUEST = 'ADD_COMMENT_REQUEST'
export const ADD_COMMENT_SUCCESS = 'ADD_COMMENT_SUCCESS'
export const ADD_COMMENT_FAILURE = 'ADD_COMMENT_FAILURE'

export const LIKE_POST_REQUEST = 'LIKE_POST_REQUEST';
export const LIKE_POST_SUCCESS = 'LIKE_POST_SUCCESS';
export const LIKE_POST_FAILURE = 'LIKE_POST_FAILURE';

export const UNLIKE_POST_REQUEST = 'UNLIKE_POST_REQUEST';
export const UNLIKE_POST_SUCCESS = 'UNLIKE_POST_SUCCESS';
export const UNLIKE_POST_FAILURE = 'UNLIKE_POST_FAILURE';



export const addPostAction = (data) => {
    return {
        type: ADD_POST_REQUEST,
        data
    }
}

export const addCommentAction = (data) => {
    return {
        type: ADD_COMMENT_REQUEST,
        data
    }
}

const reducer = (state = initialState, action) => {
    return produce(state, (draft) => {
        switch (action.type) {
            case LOAD_POSTS_REQUEST:
                draft.loadPostsLoading = true;
                draft.loadPostsDone = false;
                draft.loadPostsError = null;
                break;
            case LOAD_POSTS_SUCCESS:
                draft.loadPostsLoading = false;
                draft.loadPostsDone = true;
                draft.mainPosts = action.data.concat(draft.mainPosts);
                draft.hasMorePosts = draft.mainPosts.length < 50;
                break;
            case LOAD_POSTS_FAILURE:
                draft.loadPostsLoading = false;
                draft.loadPostsError = action.error;
                break;

            case ADD_POST_REQUEST:
                draft.addPostLoadding = true
                draft.addPostDone = false
                draft.addPostErr = null

                break;
            case ADD_POST_SUCCESS:
                draft.addPostLoadding = false
                draft.addPostDone = true
                draft.mainPosts.unshift(action.data)

                break;
            case ADD_POST_FAILURE:
                draft.addPostLoadding = false
                draft.addPostErr = action.err

                break;
            case REMOVE_POST_REQUEST:
                draft.removePostLoadding = true
                draft.removePostDone = false
                draft.removePostErr = null
                break;

            case REMOVE_POST_SUCCESS:
                draft.removePostLoadding = false
                draft.removePostDone = true
                draft.mainPosts = state.mainPosts.filter((item) => item.id !== action.data.PostId)
                break;

            case REMOVE_POST_FAILURE:
                draft.removePostLoadding = false
                draft.removePostErr = action.err
                break;

            case ADD_COMMENT_REQUEST:
                draft.addCommentLoadding = true
                draft.addCommentDone = false
                draft.addCommentErr = null
                break;

            case ADD_COMMENT_SUCCESS:
                const post = draft.mainPosts.find((item) => { return item.id === action.data.PostId })
                post.Comments.unshift(action.data)

                draft.addCommentLoadding = false
                draft.addCommentDone = true
                break;

            case ADD_COMMENT_FAILURE:
                draft.addCommentLoadding = false
                draft.addCommentErr = action.error

            case LIKE_POST_REQUEST:
                draft.likeLoading = true
                draft.likeDone = false
                draft.likeError = null
                break;

            case LIKE_POST_SUCCESS: {
                draft.likeLoading = false
                draft.likeDone = true
                const post = draft.mainPosts.find((item) => item.id === action.data.PostId)
                post.Likers.push({id: action.data.UserId})
                break;
            }
            case LIKE_POST_FAILURE:
                draft.unLikeLoading = false
                draft.unLikeError = true

            case UNLIKE_POST_REQUEST:
                draft.unLikeLoading = true
                draft.unLikeDone = false
                draft.unLikeError = null
                break;

            case UNLIKE_POST_SUCCESS: {
                draft.unLikeLoading = false
                draft.unLikeDone = true
                const post = draft.mainPosts.find((v) => v.id === action.data.PostId);
                post.Likers = post.Likers.filter((v) => v.id !== action.data.UserId);
                break;
            }
            case UNLIKE_POST_FAILURE:
                draft.unLikeLoading = false
                draft.unLikeDone = true

            default:
                return state
        }
    })
}

export default reducer

0

zerocho

지금 그것보다 mainPosts[0]이 더 문제인데요?? 저 부분은 언제부터 있는건가요?

0

uphoon

처음에 posts get으로 가져올때는 멀쩡하게 가지고오는데 지금 상태는 닉네임변경 후에 메인화면으로 다시가서 게시물 다시불러올때 저상태로 되더라구요 ㅠ

0

zerocho

네 그러니까 mainPosts[0] 부분이 정확히 언제 생기는지가 중요합니다. 리덕스에서 스테이트 추적이 되잖아요? 스테이트들을 올려주세요

0

uphoon

image

0

uphoon

image

0

uphoon

새고로침 시 닉네임 변경전 게시글은 삭제 됩니다 ㅠ

넥스트 버젼 질문

0

75

2

로그인시 401 Unauthorized 오류가 뜹니다

0

88

1

무한 스크롤 중 스크롤 튐 현상

0

172

1

특정 페이지 접근을 막고 싶을 때

0

103

2

createGlobalStyle의 위치와 영향범위

0

94

2

인라인 스타일 리렌더링 관련

0

90

2

vsc 에서 npm init 설치시 오류

0

146

2

nextjs 15버전 사용 가능할까요?

0

158

1

화면 새로고침 문의

0

120

1

RTK에서 draft, state 차이가 있나요?

0

152

2

Next 14 사용해도 될까요?

0

452

1

next, node 버전 / 폴더 구조 질문 드립니다.

0

348

1

url 오류 질문있습니다

0

211

1

ssh xxxxx로 우분투에 들어가려니까 port 22: Connection timed out

0

372

1

sudo certbot --nginx 에러

0

1271

2

Minified React error 콘솔에러 (hydrate)

0

469

1

카카오 공유했을 때 이전에 작성했던 글이 나오는 버그

0

246

1

프론트서버 배포 후 EADDRINUSE에러 발생

0

325

1

npm run build 에러

0

517

1

front 서버 npm run build 중에 발생한 에러들

0

381

1

서버 실행하고 브라우저로 들어갔을때 404에러

0

336

2

css 서버사이드 랜더링이 적용되지 않아서 문의 드립니다.

0

284

1

팔로워 3명씩 불러오고 데이터 합쳐주는걸로 바꾸고 서버요청을 무한으로하고있습니다.

0

235

2

해시태그 검색에서 throttle에 관해 질문있습니다.

0

200

1