Reputation: 48
this is my first time here
I am working on a website that shows infos about movies and tv shows using TMDB API, React, Redux and React Router Dom. I wanted to sort movies by genres and page. So in my Movies Page, i have a list of genres and each one of them has an ID which make my useEffect() hooks to rerender each time a new genre is clicked or the page is changed.
The link to the movies page looks like this movies/:genreID/:pageNumber. So basically, the idea was each time a genre is clicked or the page is changed, the url updates and i get the new genreID and pageNumber from it using useParams(), then i send them to dispatch and the component rerender.
My code looks like this
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>
The problem is that if i am on page 3 for example, and i press the browser's back button to return to page 2, I see that the link changes in the browser but the component is not updated. Same thing with the genres. If I quit Action for Adventure and hit the back button to go back to Action, I see the link changes but the component is not refreshed.
Has anyone ever encountered this kind of problem? Thank you for any help you can offer
Upvotes: 1
Views: 1320
Reputation: 878
The problem is here:
const { genreID, pageNumber } = useParams();
const [genres, setGenres] = useState(genreID);
const [page, setPage] = useState(pageNumber);
You are initialising your state with dynamic props value, but state's default value will never change, because useState is only called once. You can try printing out genreID
and pageNumber
, and genres
& page
to find out that.
Solution
You can directly use { genreID, pageNumber }
throughout your Movies
component. If you really need to store them in state, use useEffect
like this:
useEffect(()=>{
setGenres(genreID)
setPage(pageNumber)
},[genreID, pageNumber])
I made a very simple demo for you to have a clear vision on this type of problem.
Upvotes: 1
Reputation: 48
So the index.js file looks like this
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>
Upvotes: 0