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



这是我第一次来

我正在一个网站上工作,该网站使用TMDB API、React、Redux和React Router Dom显示有关电影和电视节目的信息。我想按类型和页面对电影进行分类。因此,在我的电影页面中,我有一个流派列表,每个流派都有一个ID,每当点击新的流派或页面更改时,我的useEffect((就会挂钩重新发布。

电影页面的链接如下所示:电影/:genreID/:pageNumber。因此,基本上,我们的想法是,每次点击一个流派或页面更改时,url都会更新,我使用useParams((从中获得新的genreID和pageNumber,然后我将它们发送给dispatch和组件reender。

我的代码看起来像这个

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,我会看到链接发生了更改,但组件没有刷新。

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

问题就在这里:

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

您正在使用动态props值初始化状态,但状态的默认值永远不会改变,因为useState只被调用一次。您可以尝试打印出genreIDpageNumber,以及genres&page来发现这一点。

解决方案

您可以在整个Movies组件中直接使用{ genreID, pageNumber }。如果您真的需要将它们存储在状态中,请使用useEffect,如下所示:

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

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

所以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>

最新更新