JuneStudy
JuneStudy
JuneStudy
전체 방문자
오늘
어제
  • 분류 전체보기 (21)
    • WIL (4)
    • 알고리즘 (6)
    • 개발 (11)
      • HTML+CSS+Javascript 기본 (0)
      • Typescript (5)
      • React (6)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
JuneStudy

JuneStudy

WIL

항해99-week10

2021. 12. 7. 11:44

이번주는 게시물 검색, 정렬, 마이페이지에 있는 게시물 좋아요, 댓글 페이지네이션, 권한없는 페이지에 접근 시 메인페이지 or 로그인 페이지로 redirect 하는 기능을 프로젝트에 적용했다.

어려웠던 점 및 해결

  1. 게시물 검색 기능 버튼 or 엔터 이벤트 함수를 실행 전에 onChange로 인해 미리적용되는 이슈
  2. 해결: onChange에 있는 keyword 변수를 바로 적용 하니까 검색 함수를 실행을 안시켜도 onChange이벤트가 발생할때마다 게시물을 불러왔다. 이것을 방지하기 위해 useState를 이용하여 하나의 state를 더 만들어 검색 클릭 or 엔터 이벤트 시 새로운 state에 검색어를 set 하여 문제를 해결했다. state를 두개를 사용하지 않아도 될 것 같아 나중에 리팩토링 할 때 코드를 간소화 시킬 예정이다.
// postList.js
const [keywordInput, setKeywordInput] = useState("");
const [keyword, setKeyword] = useState(queryKeyword ? queryKeyword : "");

const changeKeyword = (e) => {
    setKeywordInput(e.target.value);
};
const onEnterKeywordInput = () => {
    setKeyword(keywordInput);
};

useEffect(() => {
    // 필터, 검색어, 정렬이 변할때마다 쿼리스트링 수정 및 api요청
    ${keyword ? "&keyword=" + keyword : ""}&page=1`;
    dispatch(postActions.getFilterPostDB(setQueryString, 0));
}, [keyword]);

return(
<SearchInput
    onSubmit={onEnterKeywordInput}
    onChange={changeKeyword}
    value={keywordInput}
    placeholder="내가 관심 있는 주제를 입력해보세요."
    onKeyPress={(e) => {
      if (e.key === "Enter") {
        onEnterKeywordInput();
      }
    }}
/>
);
  1. 마이페이지 내 게시물, 북마크 게시물이 메인페이지 게시물과 redux 모듈이 분리되어있고, 내 게시물 북마크 게시물도 store 내 list가 분리되어있지만 같은 cardPost 컴포넌트를 사용하여 좋아요 시 에러나는 이슈
  2. 해결: 일단은 분리되어있는 대로 middleware와 action을 다 나누어서 만들어주었다. 리팩토링 할때 모듈까지 다 합쳐서 리스트를 하나로 합치거나, mypage, main page만 나누고 page안에서는 list를 합치는식으로 리팩토링 할 예정이다.
  3. 댓글 페이지네이션은 아직 완벽하게 구현을 하지 못했다. 페이지네이션 작동은 하지만, 10페이지 이상 시 10페이지까지만 보여주고 뒤로갈때 11페이지를 보여주는 기능, 다음페이지로 가는 버튼, 첫페이지 마지막페이지로 가는 버튼 등 구현 예정이다.
  4. 로그인 비로그인 처리와 게시물 수정 삭제에 대한 버튼을 가리는 등 뷰 처리는 했지만, url을 직접 입력해서 접근하는 방식은 처리를 못했었다.
  5. 해결: 현재는 직접 url을 입력하여 접근 시 메인페이지로 보내거나, 로그인 페이지로 보내는 방식으로 해결했다.
//app.js

function App() {
  const dispatch = useDispatch();
  const location = useSelector((state) => state.router.location?.pathname);
  const user = useSelector((state) => state.user.user);
  const userTokenInLocalStorage = localStorage.getItem("user");
  useEffect(() => {
    // 사용자 정보가 리덕스에는 없지만 로컬 스토리지에는 있을 때? SET_USER 실행
    if (!user && userTokenInLocalStorage) {
      dispatch(userActions.setUser(localStorage.getItem("user")));
    }
    // 사용자 정보가 리덕스에는 있지만 로컬 스토리지에는 없을 때? 로그인 정보 초기화
    if (user && !userTokenInLocalStorage) {
      dispatch(userActions.setUser(null));
    }
  }, [dispatch, user, userTokenInLocalStorage]);

  return (
    <div>
      {!location.includes("/edit") && location !== "/write" ? <Header /> : null}
      <ConnectedRouter history={history}>
        <Switch>
          <PublicRoute restricted component={SignUp} path="/signup" exact />
          <PublicRoute restricted component={Login} path="/login" exact />
          <PublicRoute
            restricted
            component={KakaoLoginRedirection}
            path="/api/kakao/callback"
            exact
          />
          <Route component={Main} path="/" exact />
          <Route component={PostList} path="/list" exact />
          <Route component={PostDetail} path="/detail/:id" exact />
          <Route component={MyPage} path="/mypage/:id" exact />
          <PrivateRoute component={PostWrite} path="/write" exact />
          <PrivateRoute component={PostWrite} path="/edit/:id" exact />
          {user?.userId === parseInt(location.split("/")[2]) ? (
            <Route component={UserEdit} path="/userEdit/:id" exact />
          ) : (
            <Redirect to="/"/>
          )}
          <Route component={NotFound} />
        </Switch>
      </ConnectedRouter>
      <Footer></Footer>
    </div>
  );
}

export default App;
//PublicRoute.js

import React from 'react';
import isLogin from "../lib/isLogin";
import { Route, Redirect} from "react-router";

const PublicRoute = ({component:Component,restricted, ...rest}) => {
    console.log(isLogin());
    return(
        <Route
      {...rest}
      render={(props) => (isLogin() && restricted ? <Redirect to="/" /> : <Component {...props} />)}
    />
    );
};

export default PublicRoute;
// PrivateRoute.js

import React from "react";
import isLogin from "../lib/isLogin";
import { Route, Redirect } from "react-router";

const PrivateRoute = ({ component: Component, ...rest }) => {
  return (
    <Route
      {...rest}
      render={(props) =>
        isLogin() ? <Component {...props} /> : <Redirect to="/login" />
      }
    />
  );
};

export default PrivateRoute;

로그인, 회원가입 페이지는 PublicRoute 를 사용 해 로그인이 되어있을 시 메인페이지로 redirect 하고 로그인이 안되어있으면 해당 페이지로 이동하도록 했다.

로그인을 안했을 때 접근을 하면 안되는 페이지는 PrivateRoute를 사용 해 로그인이 안되어있을 시 로그인페이지로 redirect하고 로그인이 되어있으면 접근이 가능하다.

하지만 아직 해결이 안 된 부분은 게시물 수정페이지다. 게시물 수정 페이지는 parameter가 postId 로 되어있어서 userId와 비교를 할 수가 없다. 현재 구조에서는 비교가 불가능하여 백엔드와 협의하여 수정페이지에 접근 시 조회하는 api를 만들어야 할 것 같다.

아직 프로젝트에 많은 구멍이 있지만 조만간 다 메울 예정이다.

'WIL' 카테고리의 다른 글

항해99-week9  (0) 2021.12.07
항해99-week7  (0) 2021.12.07
항해99 - week6  (0) 2021.12.07
    'WIL' 카테고리의 다른 글
    • 항해99-week9
    • 항해99-week7
    • 항해99 - week6
    JuneStudy
    JuneStudy

    티스토리툴바