简体   繁体   中英

I get the error 'TypeError: Cannot read property 'map' of undefined' when submitting a empty search request

On successful api calls it runs fine but when I try to handle an empty search it gives me an error, I have checked the code it should render the error message. When clicking the search btn i get the error. It should render text saying query must be provided. I thought it might be the render logic in my search component but i dont see the problem. I also checked the state and the reducer but no luck


// 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;
  }
};


在此处输入图片说明

Your payload is probably empty as you didn't get any results.

Try replacing this line of code:

movies: action.payload

By this, to add an undefined check:

movies: action.payload || []

Haha wow im such a newb, thank you! The result of staring code way to long.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM