Redux 공식 홈페이지 따라하기

Redux 공식 홈페이지 따라하기 - Redux 데이터 사용(1)

vitamin3000 2024. 12. 4. 22:10

 

 

이전 포스트에서 Redux 로직을 사용하는 핵심 단계를 알았으니, 소셜 미디어 피드 기능 추가로

단일 게시물 보기, 기존 게시물 편집, 게시물 작성자 세부 정보 보기, 게시물 타임스탬프, 반응 버튼 등이 있다.

 

단일

React Router를 사용하여 페이지 URL를 설정할 수 있는데, 예를 들어 /post/123 같은, 123은 게시물의 ID

import React from 'react'
import { useSelector } from 'react-redux'

export const SinglePostPage = ({ match }) => { // 찾고있는 URL 정보를 포함하는 prop
  const { postId } = match.params // 경로인 postId, 구문 분석하도록 지시하는 match.params

  const post = useSelector(state =>
    state.posts.find(post => post.id === postId) // 배열을 반복하고 찾고있는 ID의 배열 찾기
  )

 

이때 useSelector를 사용하고있는데, 값이 새 참조로 변경될 때마다 구성 요소가 다시 렌더링되는 특징에 주의하라

 

  • 만약 스토어에 일치하는 게시물 항목이 없는 경우(사용자 URL을 직접 입력하려고 하거나, 올바른 데이터가 없는 경우)
    • 객체 대신 find()는 undefined를 반환하는데 구성요소는 이를 확인하고 404에러 등 페이지를 띄울 수 있다.
  • 저장소에 올바른 게시물 객체가 있다고 가정하면 useSelector는 해당 객체를 반환하고 이것을 사용하여 게시물의 제목과 내용을 렌더링 할 수 있다.

 

단일 게시물

이제, <SinglePostPage>를 통해 해당 구성 요소를 표시할 경로를 정의하고, 첫 페이지 피드의 각 게시물에 대한 링크를 추가할 수 있다.

 

<Route exact path="/posts/:postId" component={SinglePostPage} />

 

그런 다음, 해당 게시물로 라우팅되는 <Link>로 목록 렌더링인 <PostList>를 업데이트한다.

      <Link to={`/posts/${post.id}`} className="button muted-button">
        View Post
      </Link>

 

이제 다른 페이지로 이동하므로, 주요 게시물로 돌아가는 링크도 추가한다.

          <div className="navLinks">
            <Link to="/">Posts</Link>
          </div>

 

게시물 편집

postSlice를 통해 새로운 리듀서 함수와 액션을 생성하도록 업데이트한다.

 

그러긴 위해서 호출 내부에서 객체 createSlice()에 reducers 함수(postUpdated)를 추가해야 한다.

 

게시물 객체를 업데이트하려면 다음 사항을 알아야 한다.

  • 업데이트되는 게시물의 ID를 통해 상태에서 올바른 게시물 객체를 찾을 수 있다.
  • 사용자가 입력한 새 필드 title와 필드 content

 

게시물 Redux 액션 객체는 다음과 같이 정의할 수 있다.

 

{
	type: 'osts/postUpdated', // 보통 action을 설명
    payload: {id, title, content}
 }

 

위의 액션을 넣어 생성된 createSlice 액션 객체에 action.payload로 입력된다

 

따라서, 액션 생성자에게 postUpdated를 포함하는 객체에 액션 생성자에게 인수로 전달할 수 있다.

 

리듀서는 액션이 전송될 때 상태를 실제로 어떻게 업데이트해야하는지 결정해야하는 역할을 수행한다.

따라서 리듀서가 ID를 기반으로 올바른 게시물 객체를 찾고 해당 게시물의 ttile 및 content를 구체적으로 업데이트할 수 있어야 한다.

 

마지막으로, 사용자가 게시물을 저장할 때 createSlice를 활용해 UI가 새 액션을 전송할 수 있도록 생성된 액션 생성자 함수인 postUpdated를 내보내야 한다.

 

모든 요구 사항을 고려했을 때의 postsSlice이다.

 

const postsSlice = createSlice({
  name: 'posts',
  initialState,
  reducers: {
    postAdded(state, action) {
      state.push(action.payload)
    },
    postUpdated(state, action) { //액션 생성자 함수
      const { id, title, content } = action.payload
      const existingPost = state.find(post => post.id === id)
      if (existingPost) {
        existingPost.title = title
        existingPost.content = content
      }
    }
  }
})

export const { postAdded, postUpdated } = postsSlice.actions

export default postsSlice.reducer

 

 

! 주의 : 액션에 고유 ID나 다른 임의의 값이 포함되어야 하는 경우, 항상 먼저 생성하여 액션 객체에 넣어야한다.

왜냐하면.. 리듀서는 임의의 값을 계산하지 말아야하기 때문이다 그 이유는 결과가 예측 불가가 되기 때문

 

만약 postAdded라는 액션 생성기를 직접 작성한다면 ..

// hand-written action creator
function postAdded(title, content) {
  const id = nanoid()
  return {
    type: 'posts/postAdded',
    payload: { id, title, content }
  }
}

 

하지만 Redux Toolkit은 createSlice를 통해 액션 생성자를 생성하게 해주므로

우리는 action.playload에 대한 정의만 필요하다.