React

3. Diary 만들기 (Redux-Toolkit, axios.delete, detail)

ji_su_04 2023. 2. 1. 21:04

이제 삭제와 디테일 페이지를 구현해보자.

나는 디테일 페이지에 수정, 삭제를 만들려고 생각했으니 우선 디테일 페이지 구현> 삭제 순서로 진행했다.

 

<Router.js>

const Router = () => {
  return (
    <BrowserRouter>
      <Header />
      <Routes>
        <Route path="/" element={<Main />} />
        <Route path="/:id" element={<Detail />} />
      </Routes>
      <Footer />
    </BrowserRouter>
  );
};

처음엔 모달로 구현하려 했는데 계획을 바꿔 페이지로 구현했다.

우선 Router에 Detail 페이지를 넣어주고 값은 id로 받아오게 하자.

const Diarys = ({ diary }) => {
  const navigate = useNavigate();
  const handleDetailPageLink = () => {
    navigate(`/${diary.id}`);
  };
  return (
    <DiarysDiv onClick={handleDetailPageLink}>
      <DiarysBorder>
        <DiarysDate>{diary.date}</DiarysDate>
        <DiarysTitle>{diary.title}</DiarysTitle>
        <DiarysContent>{diary.content}</DiarysContent>
      </DiarysBorder>
    </DiarysDiv>
  );
};

Diarys.jsx 컴포넌트에 디테일 페이지로 이동하는 네비를 추가해준다.

Diary에 map함수를 썼으니 diary.id를 받으면 된다.

<Detail.jsx>

const Detail = () => {
  const dataId = useParams();
  const dispatch = useDispatch();
  const diarys = useSelector((state) => state.diarys.diarys);

  useEffect(() => {
    dispatch(__getDiarys());
  }, []);

  return (
    <DetailDiv>
      <DetailBorder>
        {diarys.map((item) => {
          return (
            <div key={item.id}>
              <DetailBox item={item} dataId={dataId} />
            </div>
          );
        })}
      </DetailBorder>
    </DetailDiv>
  );
};

Diary.jsx와 크게 다른건 없다.

다른건 useParams를 사용해서 id값을 받아오는 점이다.

여기서 DetailBorder로 값을 넘겨준다.

<DetailBox.jsx>

const DetailBox = ({ item, dataId }) => {
  const dispatch = useDispatch();
  const navigate = useNavigate();
  const handleRemove = () => {
    dispatch(__deleteDiaryThunk(item.id));
    navigate("/");
  };
  return (
    <div>
      {item.id == dataId.id && (
        <>
          <DetailDiv>
            <DetailDate>{item.date}</DetailDate>
            <ButtonDiv />
            <DetailButton>수정</DetailButton>
            <DetailButton onClick={handleRemove}>삭제</DetailButton>
            <DetailButton
              onClick={() => {
                navigate("/");
              }}
            >
              뒤로
            </DetailButton>
          </DetailDiv>
          <DetailTitle>{item.title}</DetailTitle>
          <DetailContent>{item.content}</DetailContent>
        </>
      )}
    </div>
  );
};

넘겨준 data.id와 map 함수를 이용한 item.id가 같은 값만 불러오면 클릭한 박스의 값만을 가져올 수 있다.

여기서 삭제버튼 클릭시 네비를 통해 다시 메인으로 돌아가면 된다.

<diarys.js>

export const __deleteDiaryThunk = createAsyncThunk(
  "DELETE_DIARY",
  async (arg, thunkAPI) => {
    try {
      await axios.delete(`http://localhost:4000/diarys/${arg}`);
      return thunkAPI.fulfillWithValue(arg);
    } catch (err) {
      console.log(err);
      return thunkAPI.rejectWithValue(err);
    }
  }
);

const diarysSlice = createSlice({
  name: "diarys",
  initialState,
  extraReducers: {
    [__getDiarys.fulfilled]: (state, action) => {
      state.diarys = action.payload;
    },
    [__addDiaryThunk.fulfilled]: (state, action) => {
      state.diarys.push(action.payload);
    },
    [__deleteDiaryThunk.fulfilled]: (state, action) => {
      state.diarys = state.diarys.filter((item) => item.id !== action.payload);
    },
  },

삭제는 axios의 delete를 이용하고 extraReducers에 filter를 걸어주면 된다.

기능을 확인해보면 디테일 페이지에서 정상적으로 삭제와 뒤로가기에 되는 것을 확인할 수 있다.

반응형