使用 React 路由器 dom 处理浏览器后退按钮

时间:2021-01-04 12:23:11

标签: javascript reactjs react-router react-router-dom

这是我第一次来这里

我正在开发一个使用 TMDB API、React、Redux 和 React Router Dom 显示电影和电视节目信息的网站。 我想按流派和页面对电影进行排序。所以在我的电影页面中,我有一个流派列表,每个流派都有一个 ID,它使我的 useEffect() 钩子在每次单击新流派或更改页面时重新呈现。

电影页面的链接看起来像这样movies/:genreID/:pageNumber。所以基本上,这个想法是每次点击一个流派或更改页面时,url 更新,我使用 useParams() 从中获取新的流派 ID 和 pageNumber,然后我将它们发送到 dispatch 和组件重新渲染。

我的代码是这样的

const Movies = ({ isFrench, isOpen }) => {

  const dispatch = useDispatch();
  const history = useHistory();
  const { genreID, pageNumber } = useParams();

  const language = isFrench ? "fr" : "";
  const [genres, setGenres] = useState(genreID);
  const [page, setPage] = useState(pageNumber);

  useEffect(() => {
    dispatch(fetchMovies(language, page, genres));
    history.push(`movies/${genres}/${page}`);
  }, [dispatch, language, page, genres, history]);

  const { popularMovies, numOfPages, isLoading } = useSelector(
    (state) => state.movies
  );

  //Change Category
  const changeCategoryHandler = (id) => {
    setPage(1);
    setGenres(id);
    getCategoryName(id);
  };

  //Print categories
  const frenchCategories = categoriesMoviesFR.map((category) => (
    <li onClick={() => changeCategoryHandler(category.id)} id={category.id}>
      {category.name}
    </li>
  ));
  
  ... 
  }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

问题是,例如,如果我在第 3 页上,然后按浏览器的后退按钮返回到第 2 页,我会看到浏览器中的链接发生了变化,但组件没有更新。流派也是一样。如果我退出 Action for Adventure 并点击后退按钮返回 Action,我会看到链接发生变化,但组件没有刷新。

有人遇到过这种问题吗? 感谢您提供的任何帮助

2 个答案:

答案 0 :(得分:1)

问题出在这里:

  const { genreID, pageNumber } = useParams();
  const [genres, setGenres] = useState(genreID);
  const [page, setPage] = useState(pageNumber);

您正在使用动态道具值初始化您的状态,但状态的默认值永远不会改变,因为 useState 只被调用一次。您可以尝试打印出 genreIDpageNumber,以及 genrespage 以找出答案。

解决方案

您可以在整个 { genreID, pageNumber } 组件中直接使用 Movies。如果您确实需要将它们存储在状态中,请像这样使用 useEffect

useEffect(()=>{
  setGenres(genreID)
  setPage(pageNumber)
},[genreID, pageNumber])

我做了一个非常简单的demo,让您对这类问题有一个清晰的认识。

答案 1 :(得分:0)

所以 index.js 文件看起来像这样

import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import { createStore, applyMiddleware, compose } from "redux";
import { Provider } from "react-redux";
import rootReducer from "./reducers";
import thunk from "redux-thunk";
import { BrowserRouter } from "react-router-dom";


const composeEnhancer = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

const store = createStore(rootReducer, composeEnhancer(applyMiddleware(thunk)));

ReactDOM.render(
  <BrowserRouter>
    <React.StrictMode>
      <Provider store={store}>
        <App />
      </Provider>
    </React.StrictMode>
  </BrowserRouter>,
  document.getElementById("root")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>