こちらのサイトの内容をTypeScriptで書いているのですが、エラーの解消方法を教えていただきたいです。
エディタ上でのエラーは出ていないのですがブラウザ上でエラーが出ています。
インターネットでこのエラーを調べるとタイプミスであったり、値が与えられてなかったりしていたのですが自分で見る限り見つけることはできませんでした。下にコードを貼っておきます。
TypeScript
1 2/*Search.tsx*/ 3 4import React, { useState } from 'react'; 5 6export interface SearchProps { 7 search: (searchValue: string) => void 8} 9 10const Search = (props: SearchProps) => { 11 const [searchValue, setSearchValue] = useState(''); 12 13 const handleSearchInputChanges = (e: React.ChangeEvent<HTMLInputElement>) => { 14 setSearchValue(e.target.value); 15 }; 16 17 const resetInputField = () => { 18 setSearchValue(''); 19 }; 20 21 const callSearchFunction = (e: React.MouseEvent<HTMLInputElement, MouseEvent>) => { 22 e.preventDefault(); 23 props.search(searchValue); 24 resetInputField(); 25 }; 26 27 return ( 28 <form className='search'> 29 <input 30 value={searchValue} 31 onChange={handleSearchInputChanges} 32 type="text" 33 /> 34 <input onClick={callSearchFunction} value='SEARCH' type="submit" /> 35 </form> 36 ); 37 38}; 39 40export default Search;
TypeScript
1 2/*Movie.tsx*/ 3 4import React from 'react'; 5 6const DEFAULT_PLACEHOLDER_IMAGE = 'https://m.media-amazon.com/images/M/MV5BMTczNTI2ODUwOF5BMl5BanBnXkFtZTcwMTU0NTIzMw@@._V1_SX300.jpg'; 7 8export interface MovieObj { 9 Poster: string, 10 Title: string, 11 Year: number, 12} 13 14const Movie: React.FC<{ movie: MovieObj }> = ({ movie }) => { 15 const poster = 16 movie.Poster === 'N/A' 17 ? DEFAULT_PLACEHOLDER_IMAGE 18 : movie.Poster; 19 20 return ( 21 <div className="movie"> 22 <h2>{movie.Title}</h2> 23 <div> 24 <img 25 width="200" 26 src={poster} 27 alt={`The movie titled: ${movie.Title}`} 28 /> 29 </div> 30 <p>({movie.Year})</p> 31 </div> 32 ); 33}; 34 35export default Movie;
TypeScript
1 2/*App.tsx*/ 3 4import React, { useEffect, useReducer } from 'react'; 5import '../App.css'; 6import Header from './Header'; 7// eslint-disable-next-line no-unused-vars 8import Movie, { MovieObj } from './Movie'; 9import Search from './Search'; 10 11const MOVIE_API_URL = 'http://www.omdbapi.com/?i=tt3896198&apikey=db671368'; 12 13 14interface ISearchMoviesRequest { 15 type: 'SEARCH_MOVIES_REQUEST' 16} 17 18interface ISearchMoviesSuccess { 19 type: 'SEARCH_MOVIES_SUCCESS', 20 payload: MovieObj[] 21} 22 23interface ISearchMoviesFailure { 24 type: 'SEARCH_MOVIES_FAILURE', 25 error: string 26} 27 28type IActions = 29 | ISearchMoviesRequest 30 | ISearchMoviesSuccess 31 | ISearchMoviesFailure; 32 33interface IState { 34 loading: boolean, 35 movies: MovieObj[], 36 errorMessage: string | null 37} 38 39const initialState: IState = { 40 loading: true, 41 movies: [], 42 errorMessage: null 43}; 44 45const reducer = (state: IState, action: IActions): IState => { 46 switch (action.type) { 47 case 'SEARCH_MOVIES_REQUEST': 48 return { 49 ...state, 50 loading: true, 51 errorMessage: null 52 }; 53 case 'SEARCH_MOVIES_SUCCESS': 54 return { 55 ...state, 56 loading: false, 57 movies: action.payload 58 }; 59 case 'SEARCH_MOVIES_FAILURE': 60 return { 61 ...state, 62 loading: false, 63 errorMessage: action.error 64 }; 65 default: 66 return state; 67 } 68}; 69 70const App = () => { 71 const [state, dispatch] = useReducer(reducer, initialState); 72 73 useEffect(() => { 74 75 fetch(MOVIE_API_URL) 76 .then(response => response.json()) 77 .then(jsonResponse => { 78 79 dispatch({ 80 type: 'SEARCH_MOVIES_SUCCESS', 81 payload: jsonResponse.Search 82 }); 83 }); 84 }, []); 85 86 const search = (searchValue: string): void => { 87 dispatch({ 88 type: 'SEARCH_MOVIES_REQUEST' 89 }); 90 91 fetch(`http://www.omdbapi.com/?i=${searchValue}&apikey=db671368`) 92 .then(response => response.json()) 93 .then(jsonResponse => { 94 if (jsonResponse.response === 'True') { 95 dispatch({ 96 type: 'SEARCH_MOVIES_SUCCESS', 97 payload: jsonResponse.Search 98 }); 99 } else { 100 dispatch({ 101 type: 'SEARCH_MOVIES_FAILURE', 102 error: jsonResponse.Error 103 }); 104 } 105 }); 106 }; 107 108 const { movies, errorMessage, loading } = state; 109 110 return ( 111 <div className="App"> 112 <Header text="HOOKED" /> 113 <Search search={search} /> 114 <p className="App-intro">Sharing a few of our favourite movies</p> 115 <div className="movies"> 116 {loading && !errorMessage 117 ? (<span>loading... </span>) 118 : errorMessage 119 ? (<div className="errorMessage">{errorMessage}</div>) 120 : (movies.map((movie: MovieObj, index: number) => ( 121 <Movie key={`${index}-${movie.Title}`} movie={movie} /> 122 )) 123 )} 124 </div> 125 </div> 126 ); 127}; 128 129export default App;
1つ自信がない部分がApp.tsx
のconst App = () => {}
でのfetch
内で、APIを使ったことがなくかつTypeScriptも初学習であるため合っているのかわからないです。(そこでmovies
に値が渡されていない?)
よろしくお願いいたします。
環境 React: 16.12.0 TypeScript: 3.7.5
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/02/11 21:58