为什么 useSelector return 未定义?
why useSelector return undefined?
当我使用 useSelector
时,我不明白为什么它返回未定义
在控制台日志中显示 Uncaught TypeError: movies.results is undefined
error logmovieLising.js(without render movies)
console.log
store.js
import {configureStore} from '@reduxjs/toolkit';
import moviesReducer from './movies/movieSlice';
export const store = configureStore({
reducer:{
movies:moviesReducer
}
})
movieSlice.js
这是我定义初始状态 reducer 和动作的切片
import {createSlice,createAsyncThunk} from '@reduxjs/toolkit';
import movieApi from '../../common/api/movieApi';
const API_KEY = process.env.REACT_APP_API_KEY;
export const fetchAsyncMovies = createAsyncThunk(
"movies/fetchAsyncMovies",
async () => {
const movieTerm ="harry";
const response = await
movieApi.get(`/search/movie?api_key=${API_KEY}&query=${movieTerm}`);
// console.log(response.data);
return response.data;
}
);
const initialState = {
movies:{},
}
const movieSlice = createSlice({
name:"movies",
initialState,
reducers:{
addMovies:(state,{payload}) =>{
state.movies= payload;
}
},
extraReducers:{
[fetchAsyncMovies.pending]: () => {
console.log("Pending");
},
[fetchAsyncMovies.fulfilled]: (state, { payload }) => {
console.log("Fetched Successfully!");
return { ...state, movies: payload };
},
[fetchAsyncMovies.rejected]: () => {
console.log("Rejected!");
},
}
});
export const {addMovies} = movieSlice.actions;
export const getAllMovies = (state) => state.movies.movies;
export default movieSlice.reducer
Home.js
这是我使用 useDispatch 的 Home 组件
import React, { useEffect } from 'react';
import MovieListing from '../MovieListing/MovieListing';
import {useDispatch} from "react-redux";
import {fetchAsyncMovies} from "../../features/movies/movieSlice"
const Home = () => {
const dispatch = useDispatch();
useEffect(()=>{
dispatch(fetchAsyncMovies());
},[dispatch]);
return(
<div>
<div className="banner-img"></div>
<MovieListing/>
</div>
) ;
};
export default Home;
MovieListing.js(COMPONENT)
import React from 'react';
import {useSelector} from 'react-redux';
import {getAllMovies} from '../../features/movies/movieSlice';
import MovieCard from '../MovieCard/MovieCard';
import './movieListing.scss'
const MovieListing = () => {
const movies = useSelector(getAllMovies);
let renderMovies ="";
renderMovies = movies.results.length > 0 ? (movies.results.map((movie,index)=>(
<MovieCard key={index} data={movie} />
))) :(
<div className="movies-error">
<h3>{movies.Error}</h3>
</div>
);
console.log(movies.results);
return (
<div className="movie-wrapper">
<div className="movie-list">
<h2>Movies</h2>
<div className="movie-container">
{renderMovies }
</div>
</div>
</div>
);
};
export default MovieListing;
由于您将初始状态定义为:
const initialState = { movies:{}, }
在第一个渲染中,movies.results
是 undefined
,因此尝试使用 length
属性 会导致错误。
尝试像这样定义你的初始状态:
const initialState = { movies:{results:[]}, }
另一种解决方案是在使用其属性之前始终检查是否定义了 movies.results
:
renderMovies = movies.results && movies.results.length > 0 ? ...
当我使用 useSelector
时,我不明白为什么它返回未定义在控制台日志中显示 Uncaught TypeError: movies.results is undefined
error logmovieLising.js(without render movies) console.log
store.js
import {configureStore} from '@reduxjs/toolkit';
import moviesReducer from './movies/movieSlice';
export const store = configureStore({
reducer:{
movies:moviesReducer
}
})
movieSlice.js
这是我定义初始状态 reducer 和动作的切片
import {createSlice,createAsyncThunk} from '@reduxjs/toolkit';
import movieApi from '../../common/api/movieApi';
const API_KEY = process.env.REACT_APP_API_KEY;
export const fetchAsyncMovies = createAsyncThunk(
"movies/fetchAsyncMovies",
async () => {
const movieTerm ="harry";
const response = await
movieApi.get(`/search/movie?api_key=${API_KEY}&query=${movieTerm}`);
// console.log(response.data);
return response.data;
}
);
const initialState = {
movies:{},
}
const movieSlice = createSlice({
name:"movies",
initialState,
reducers:{
addMovies:(state,{payload}) =>{
state.movies= payload;
}
},
extraReducers:{
[fetchAsyncMovies.pending]: () => {
console.log("Pending");
},
[fetchAsyncMovies.fulfilled]: (state, { payload }) => {
console.log("Fetched Successfully!");
return { ...state, movies: payload };
},
[fetchAsyncMovies.rejected]: () => {
console.log("Rejected!");
},
}
});
export const {addMovies} = movieSlice.actions;
export const getAllMovies = (state) => state.movies.movies;
export default movieSlice.reducer
Home.js
这是我使用 useDispatch 的 Home 组件
import React, { useEffect } from 'react';
import MovieListing from '../MovieListing/MovieListing';
import {useDispatch} from "react-redux";
import {fetchAsyncMovies} from "../../features/movies/movieSlice"
const Home = () => {
const dispatch = useDispatch();
useEffect(()=>{
dispatch(fetchAsyncMovies());
},[dispatch]);
return(
<div>
<div className="banner-img"></div>
<MovieListing/>
</div>
) ;
};
export default Home;
MovieListing.js(COMPONENT)
import React from 'react';
import {useSelector} from 'react-redux';
import {getAllMovies} from '../../features/movies/movieSlice';
import MovieCard from '../MovieCard/MovieCard';
import './movieListing.scss'
const MovieListing = () => {
const movies = useSelector(getAllMovies);
let renderMovies ="";
renderMovies = movies.results.length > 0 ? (movies.results.map((movie,index)=>(
<MovieCard key={index} data={movie} />
))) :(
<div className="movies-error">
<h3>{movies.Error}</h3>
</div>
);
console.log(movies.results);
return (
<div className="movie-wrapper">
<div className="movie-list">
<h2>Movies</h2>
<div className="movie-container">
{renderMovies }
</div>
</div>
</div>
);
};
export default MovieListing;
由于您将初始状态定义为:
const initialState = { movies:{}, }
在第一个渲染中,movies.results
是 undefined
,因此尝试使用 length
属性 会导致错误。
尝试像这样定义你的初始状态:
const initialState = { movies:{results:[]}, }
另一种解决方案是在使用其属性之前始终检查是否定义了 movies.results
:
renderMovies = movies.results && movies.results.length > 0 ? ...