我是react redux toolkit和redux saga的新手,遇到了一个错误,它只呈现moviedb-api的最后一个api调用值。此外,当我从useSelector控制台记录状态时,它会呈现多个值。这是我的代码
App.js
import "./App.css"; import Row from "./components/Row"; import requests from "./requests"; function App() { return ( <div className="App"> <Row title="Netflix Originals" fetchUrl={requests.fetchNetflixOriginals} /> <Row title="Trending Now" fetchUrl={requests.fetchTrending} /> {/* <Row title="Top Rated" fetchUrl={requests.fetchTopRated} /> <Row title="Action Movies" fetchUrl={requests.fetchActionMovies} /> <Row title="Horror Movies" fetchUrl={requests.fetchHorrorMovies} /> */} </div> ); } export default App;
Store.js
import { configureStore, combineReducers } from "@reduxjs/toolkit";
import createSagaMiddleware from "redux-saga";
import { watcherSaga } from "./sagas/rootSaga";
import movieReducer from "./ducks/movieSlice";
const sagaMiddleware = createSagaMiddleware();
const reducer = combineReducers({
movie: movieReducer,
});
const store = configureStore({
reducer,
middleware: [sagaMiddleware],
});
sagaMiddleware.run(watcherSaga);
export default store;
movieSlice.js
import { createSlice } from "@reduxjs/toolkit";
const movieSlice = createSlice({
name: "movie",
initialState: [],
reducers: {
getMovie() {},
setMovie(state, action) {
const movieData = action.payload;
return { ...state, ...movieData };
},
},
});
export const { getMovie, setMovie } = movieSlice.actions;
export default movieSlice.reducer;
rootSaga.js
import { takeEvery, takeLatest } from "redux-saga/effects";
import { getMovie } from "../ducks/movieSlice";
import { handleGetMovie } from "./handlers/movies";
export function* watcherSaga() {
yield takeEvery(getMovie.type, handleGetMovie);
}
处理机
movie.js
import { call, put } from "redux-saga/effects";
import { requestGetMovie } from "../requests/movies";
import { setMovie } from "../../ducks/movieSlice";
export function* handleGetMovie(action) {
try {
const response = yield call(requestGetMovie, action.payload);
const { data } = response;
yield put(setMovie(data));
} catch (error) {
console.log(error);
}
}
请求
movie.js
import axios from "axios";
const baseURL = "https://api.themoviedb.org/3";
export function requestGetMovie(url) {
const URL = baseURL + url.fetchLink;
return axios.request({
method: "get",
url: URL,
});
}
requests.js
const APIKEY = "9cf4e09bc69e9849477a8ac79d29a205";
const requests = {
fetchTrending: `/trending/all/week?api_key=${APIKEY}&language=en=us`,
fetchNetflixOriginals: `/discover/tv?api_key=${APIKEY}&with_networks=213`,
fetchTopRated: `/movie/top_rated?api_key=${APIKEY}&language=en=us`,
fetchActionMovies: `/discover/movie?api_key=${APIKEY}&with_generes=28`,
fetchHorrorMovies: `/discover/movie?api_key=${APIKEY}&with_genres=27
`,
};
export default requests;
Row.js
import React, { useState, useEffect } from "react";
import styled from "styled-components";
import { useDispatch, useSelector } from "react-redux";
import { getMovie } from "../redux/ducks/movieSlice";
function Row({ title, fetchUrl }) {
const dispatch = useDispatch();
useEffect(() => {
dispatch(
getMovie({
fetchLink: fetchUrl,
})
);
}, [dispatch, fetchUrl]);
const movie = useSelector((state) => {
return state.movie.results;
});
console.log(movie);
return (
<RowContainer>
{title}
<CardsContainer>{movie && movie[0].name}</CardsContainer>
</RowContainer>
);
}
export default Row;
const RowContainer = styled.div`
color: white;
`;
const CardsContainer = styled.div`
color: white;
`;
Netflix组织应该显示Lucifer,同时它从最新的状态值渲染Money Heist,如果我console.log电影值,即使我在app.js上只有两个行组件,也会重复多个值。如果我在app.js上有5次行组件,它会在console上显示25次值。
图像
图像2
您的问题恰恰出在文件movieSlice.js
上此处:
setMovie(state, action) {
const movieData = action.payload;
return { ...state, ...movieData };
}
每次调用setMovie
操作时,都会覆盖电影对象。
你应该做的是对不同的电影类型有不同的操作,比如:
const movieSlice = createSlice({
name: "movie",
initialState: {
trendingMovies: [],
actionMovies: [],
},
reducers: {
setTrendingMovies(state, action) {
state.trendingMovies = action.payload;
},
setActionMovies(state, action) {
state.actionMovies = action.payload;
}
},
});