这是我第一次来这里
我正在开发一个使用 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,我会看到链接发生变化,但组件没有刷新。
有人遇到过这种问题吗? 感谢您提供的任何帮助
答案 0 :(得分:1)
问题出在这里:
const { genreID, pageNumber } = useParams();
const [genres, setGenres] = useState(genreID);
const [page, setPage] = useState(pageNumber);
您正在使用动态道具值初始化您的状态,但状态的默认值永远不会改变,因为 useState 只被调用一次。您可以尝试打印出 genreID
和 pageNumber
,以及 genres
和 page
以找出答案。
解决方案
您可以在整个 { 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>