在成功的 api 调用中,它运行良好,但当我尝试处理空搜索时,它给我一个错误,我已经检查了它应该呈现错误消息的代码。单击搜索 btn 时出现错误。它应该呈现说明必须提供查询的文本。我认为这可能是我的搜索组件中的渲染逻辑,但我没有看到问题。我还检查了状态和 reducer ,但没有运气
// search component that renders movies, error message, and loading message
import React, {
Fragment,
useState,
useContext
} from 'react';
import MovieContext from '../../context/movie/movieContext';
import ErrorStyle from '../styles/ErrorStyle';
import PropTypes from 'prop-types';
import MoviesStyle from '../styles/MoviesStyle';
import MovieItem from '../movie/MovieItem';
import InputStyle from '../styles/InputStyle';
import SearchStyle from '../styles/SearchStyle';
import FormStyle from '../styles/FormStyle';
function Search() {
const movieContext = useContext(MovieContext);
const {
Search,
movies,
errorMessage,
loading
} = movieContext;
console.log(errorMessage);
const [search, setSearch] = useState('');
const handleChange = e => {
setSearch(e.target.value);
};
const clearSearch = () => {
setSearch('');
};
const searchFunction = e => {
e.preventDefault();
Search(search);
clearSearch();
};
return (<Fragment>
<FormStyle action=''>
<SearchStyle type='text' value={search} onChange={handleChange} placeholder='Search'/>
<InputStyle onClick={searchFunction} type='submit' value='SEARCH'/>
</FormStyle>
< p className='App-intro'>
Search for your favourite movies
</p>
< MoviesStyle >
{loading && !errorMessage
? (< span > loading... < /span>): errorMessage ? ( <ErrorStyle> {errorMessage} </ErrorStyle>)
: (movies.map((movie, index) => (< MovieItem key = { `${index}:${movie.Title}`} movie = {movie} />)))
}
< /MoviesStyle></Fragment>);
}
Search.protoTypes = {
search: PropTypes.string.isRequired
};
export default Search;
// state using context api, holds search function to make requests
import React, {
useReducer
} from 'react';
import MovieContext from './movieContext';
import MovieReducer from './MovieReducer';
const MovieState = props => {
const initialState = {
loading: false,
movies: [],
errorMessage: null
};
// using our reducer and initial state in useReducer
const [state, dispatch] = useReducer(MovieReducer, initialState);
// makes request to the api
const Search = searchValue => {
dispatch({
type: 'SEARCH_MOVIE_REQUEST'
});
fetch(`https://api.themoviedb.org/3/search/movie?query=${searchValue}&api_key=d107fa42623e9a747b66f9da4ec90364`).then(response => response.json()).then(jsonResponse => {
console.log(jsonResponse);
if (jsonResponse) {
dispatch({
type: 'SEARCH_MOVIE_SUCCESS',
payload: jsonResponse.results
});
} else {
dispatch({
type: 'SEARCH_MOVIE_FAILURE',
errors: jsonResponse.errors[0]
});
}
});
};
return ( < MovieContext.Provider value = {
{
loading: state.loading,
movies: state.movies,
errorMessage: state.errorMessage,
Search
}
} > {
props.children
} < /MovieContext.Provider>);
};
export default MovieState;
// reducer
export default (state, action) => {
switch (action.type) {
case 'SEARCH_MOVIE_REQUEST':
return {
...state,
loading: true,
errorMessage: null
};
case 'SEARCH_MOVIE_SUCCESS':
return {
...state,
loading: false,
movies: action.payload
};
case 'SEARCH_MOVIE_FAILURE':
return {
...state,
loading: false,
errorMessage: action.errors
};
default:
return state;
}
};
最佳答案
您的payload
可能是空的,因为您没有得到任何结果。
尝试替换这行代码:
movies: action.payload
由此,添加一个undefined
检查:
movies: action.payload || []
关于javascript - 提交空搜索请求时出现错误 'TypeError: Cannot read property ' map' of undefined',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59036576/