[React] 뒤로가기

KoEunseo·2023년 1월 3일
0

리액트

목록 보기
4/21

리액트로 투두를 만들던 도중,
뒤로가기를 할 수 없다는 사실을 깨달았다. 오매?
당연히 될줄알았는데... 아니였다!! 😱
어떤 동작을 해도 react-router-dom을 통해 쿼리를 설정해 놓지 않는 한은 url이 바뀌지가 않는다.
흠.

사실 뒤로가기를 내가 스택을 사용해서 할 수 있지 않을까 싶어서
빈배열을 만들고 클릭 이벤트가 생길 때마다 push해주었다.
여기까지는 됐는데, pop해서 화면을 나타내고싶어도 뒤로가기를 감지해야 한다는 🤔 문제가 생겼다.
그래서 그냥 구글링해봄. 아직 자세히 보지는 않았는데,
react-router-dom에 useHistory를 사용해서 url을 변경시킬 수 있다고 한다. 이 기능을 사용하면... 언뜻 생각해도 할 수 있을 것 같긴 하다.

이미 저 라이브러리를 깔아놓은 상태이기도 하구...
그래도 일단 뒤로가기를 감지하는 방법을 먼저 찾아봐야겠당

window.onpageshow = function(event) {
    if ( event.persisted || (window.performance && window.performance.navigation.type == 2)) {
        // Back Forward Cache로 브라우저가 로딩될 경우 혹은 브라우저 뒤로가기 했을 경우
        // 이벤트 추가하는 곳
        console.log('back button event');
    }
  }

navigation은 이제 사용하지 말라고 함...

'useHistory' (imported as 'useHistory') was not found in 'react-router-dom'
이라고 에러가 떠서 찾아보니 useHistory가 useNavigate가 되었다고 한다!

useParams, useNavigate로 뒤로가기 구현

  1. router할때 /todos/:id 이런식으로 안함.
    <Route path='/todos/:id' element={<TodoDetail />} />
  2. 1 대신 에 와일드카드를 줌.
    <Routes>
     <Route path='/*' element={<Todo />} />
     <Route path='/auth' element={<Login />} />
     <Route path='/signup' element={<SignUp />} />
    </Routes>
  3. useNavigate와 useParams를 사용함.
    import { useNavigate, useParams } from "react-router-dom";
    const Todo = () => {
     const [curTodo, setCurTodo] = useState();
     const { "*" : curParams} = useParams(); //구조분해할당해서 값만 가져와서 사용. 안그럼 {"*": 파라미터값} 이렇게 생겨서 쓸수가없다.
     return (
       <TodoBox>
         <h2>Todo List</h2>
         <div>
           <TodoList />
         </div>
         {
           curParams ? 
         <TodoDetail /> : null
         }
         <TodoCreate />
       </TodoBox>
     )
    };
  4. 현재 주소창의 url을 변경시키고, 주소창의 파라미터를 읽어서 파라미터가 있으면 디테일페이지 렌더링하도록 함
  5. 디테일 페이지 오픈하는 클릭 이벤트는 네비게이트 주소를 todo.id로 줌.
    const TodoItem = ({todo, setCurTodo }) => {
     const navigate = useNavigate();
     const handleOpenDetailPage = (e) => {
       navigate(`${todo.id}`);
       setCurTodo(todo.id);
     };
     return (
       <>
         <TodoItemBox key={todo.id} onClick={handleOpenDetailPage} >
           <TodoTitle>{todo.title}</TodoTitle>
           <span>{todo.createdAt}</span>
         </TodoItemBox>
       </>
     )
    }
profile
주니어 플러터 개발자의 고군분투기

0개의 댓글