eslint no-nested-ternary の対応
やりたい事
import React, { useState, useEffect } from 'react'; import '../App.css'; import Header from './Header'; import Movie from './Movie'; import Search from './Search'; const MOVIE_API_URL = 'https://www.omdbapi.com/?s=man&apikey=4a3b711b'; // you should replace this with yours const App = () => { const [loading, setLoading] = useState(true); const [movies, setMovies] = useState([]); const [errorMessage, setErrorMessage] = useState(null); useEffect(() => { fetch(MOVIE_API_URL) .then((response) => response.json()) .then((jsonResponse) => { setMovies(jsonResponse.Search); setLoading(false); }); }, []); const search = (searchValue) => { setLoading(true); setErrorMessage(null); fetch(`https://www.omdbapi.com/?s=${searchValue}&apikey=4a3b711b`) .then((response) => response.json()) .then((jsonResponse) => { if (jsonResponse.Response === 'True') { setMovies(jsonResponse.Search); setLoading(false); } else { setErrorMessage(jsonResponse.Error); setLoading(false); } }); }; return ( <div className="App"> <Header text="HOOKED" /> <Search search={search} /> <p className="App-intro">Sharing a few of our favourite movies</p> <div className="movies"> {loading && !errorMessage ? ( <span>loading...</span> ) : errorMessage ? ( <div className="errorMessage">{errorMessage}</div> ) : ( movies.map((movie, index) => ( <Movie key={`${index}-${movie.Title}`} movie={movie} /> )) )} </div> </div> ); }; export default App;
上記のコードはeslint(react/prop-types)
が発生する。
Do not nest ternary expressions. eslint(no-nested-ternary)
これは49-57行目で三項演算子を入れ子にして使用しているため。
JSX内では無名関数が使えるため、
無名関数内でIF文を使用してno-nested-ternary
を回避
import React, { useState, useEffect } from 'react'; import '../App.css'; import Header from './Header'; import Movie from './Movie'; import Search from './Search'; // 自分のAPI URLに置き換える必要がある const MOVIE_API_URL = 'https://www.omdbapi.com/?s=man&apikey=4a3b711b'; const App = () => { const [loading, setLoading] = useState(true); const [movies, setMovies] = useState([]); const [errorMessage, setErrorMessage] = useState(null); useEffect(() => { fetch(MOVIE_API_URL) .then((response) => response.json()) .then((jsonResponse) => { setMovies(jsonResponse.Search); setLoading(false); }); }, []); const search = (searchValue) => { setLoading(true); setErrorMessage(null); fetch(`https://www.omdbapi.com/?s=${searchValue}&apikey=4a3b711b`) .then((response) => response.json()) .then((jsonResponse) => { if (jsonResponse.Response === 'True') { setMovies(jsonResponse.Search); setLoading(false); } else { setErrorMessage(jsonResponse.Error); setLoading(false); } }); }; return ( <div className="App"> <Header text="HOOKED" /> <Search search={search} /> <p className="App-intro">Sharing a few of our favourite movies</p> <div className="movies"> { loading && !errorMessage ? (<span>loading...</span>) : (() => { if (errorMessage) { return (<div className="errorMessage">{errorMessage}</div>); } return (movies.map((movie) => (<Movie key={`${movie.Year}-${movie.Title}`} movie={movie} />))); })()} </div> </div> ); }; export default App;
上記のコードでeslint(no-nested-ternary)
を回避できるが、
react/no-array-index-key
が発生する。
Do not use Array index in keys eslint(react/no-array-index-key)
react/no-array-index-key
は要素のkeyに配列のインデックスを使用すると発生するエラー。
配列がソートまたは追加されたとき、indexが変更され 不要なレンダリングが発生するから警告が発生するらしい。
参考 Prevent usage of Array index in keys (react/no-array-index-key)
適当に別のkeyを指定して修正
import React, { useState, useEffect } from 'react'; import '../App.css'; import Header from './Header'; import Movie from './Movie'; import Search from './Search'; // 自分のAPI URLに置き換える必要がある const MOVIE_API_URL = 'https://www.omdbapi.com/?s=man&apikey=4a3b711b'; const App = () => { const [loading, setLoading] = useState(true); const [movies, setMovies] = useState([]); const [errorMessage, setErrorMessage] = useState(null); useEffect(() => { fetch(MOVIE_API_URL) .then((response) => response.json()) .then((jsonResponse) => { setMovies(jsonResponse.Search); setLoading(false); }); }, []); const search = (searchValue) => { setLoading(true); setErrorMessage(null); fetch(`https://www.omdbapi.com/?s=${searchValue}&apikey=4a3b711b`) .then((response) => response.json()) .then((jsonResponse) => { if (jsonResponse.Response === 'True') { setMovies(jsonResponse.Search); setLoading(false); } else { setErrorMessage(jsonResponse.Error); setLoading(false); } }); }; return ( <div className="App"> <Header text="HOOKED" /> <Search search={search} /> <p className="App-intro">Sharing a few of our favourite movies</p> <div className="movies"> { loading && !errorMessage ? (<span>loading...</span>) : (() => { if (errorMessage) { return (<div className="errorMessage">{errorMessage}</div>); } return (movies.map((movie) => (<Movie key={`${movie.Year}-${movie.Title}`} movie={movie} />))); })} </div> </div> ); }; export default App;