export 'withRouter' (imported as 'withRouter') was not found in 'react-router-dom'

Viewed 1549

I am totally a beginner in React and while practising I ran into this issue.
Through searching, I found out that 'withRouter' is not supported anymore by 'react-router-dom v6'. But I can't figure out how to change my code compatibly to v6.
Does anyone know how to change this code instead of using 'withRouter'?
Thanks in advance!

    import React, { useEffect } from 'react';
    import { useDispatch, useSelector } from 'react-redux';
    import { withRouter } from 'react-router-dom';
    import { readPost, unloadPost } from '../../modules/post';
    import PostViewer from '../../components/post/PostViewer';
    
    const PostViewerContainer = ({ match }) => {
      // 처음 마운트될 때 포스트 읽기 API요청
      const { postId } = match.params;
      const dispatch = useDispatch();
      const { post, error, loading } = useSelector(({ post, loading }) => ({
        post: post.post,
        error: post.error,
        loading: loading['post/READ_POST']
     }));
    
    useEffect(() => {
      dispatch(readPost(postId));
      // 언마운트될 때 리덕스에서 포스트 데이터 없애기
      return () => {
        dispatch(unloadPost());
      };
    }, [dispatch, postId]);
    
      return <PostViewer post={post} loading={loading} error={error} />;
    };
    
    export default withRouter(PostViewerContainer);

enter image description here

1 Answers

That is correct, the withRouter Higher Order Component (HOC) was removed in react-router-dom@6.

Since PostViewerContainer is a function component, just use the React hooks directly. There's no need really for the withRouter HOC. In this case it's the useParams hook you need to import and use.

Example:

import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useParams } from 'react-router-dom'; // <-- import useParams hook
import { readPost, unloadPost } from '../../modules/post';
import PostViewer from '../../components/post/PostViewer';

const PostViewerContainer = () => { // <-- remove match prop
  // 처음 마운트될 때 포스트 읽기 API요청
  const { postId } = useParams(); // <-- call hook and destructure param

  const dispatch = useDispatch();

  const { post, error, loading } = useSelector(({ post, loading }) => ({
    post: post.post,
    error: post.error,
    loading: loading['post/READ_POST']
  }));

  useEffect(() => {
    dispatch(readPost(postId));
    // 언마운트될 때 리덕스에서 포스트 데이터 없애기
    return () => {
      dispatch(unloadPost());
    };
  }, [dispatch, postId]);

  return <PostViewer post={post} loading={loading} error={error} />;
};

For reference, if you needed to still use an HOC for class based components you'd need to either convert them to function components or create a custom withRouter HOC.

Example:

import { useLocation, useNavigate, useParams } from 'react-router-dom';

const withRouter = Component => props => {
  const location = useLocation();
  const navigate = useNavigate();
  const params = useParams();

  return (
    <Component
      {...props}
      location={location}
      navigate={navigate}
      params={params}
    />
  );
};

export default withRouter;
Related