#javascript #reactjs #react-native #web-development-server
#javascript #reactjs #react-native #сервер веб-разработки
Вопрос:
Просто хотел узнать, могу ли я вообще получить от Unhandled Rejection (TypeError)
. Я уже ввел оператор if else, который сообщает ему отобразить то или иное. Либо результат, либо сообщение о том, что введите допустимую страну. Я уже некоторое время просматривал Веб. Пожалуйста, дайте мне знать. Спасибо. Вот мой код и изображение ошибки.
import React, { Component } from 'react';
import './App.css';
import NavBar from "./navbar";
import axios from "axios";
import Accordion from './accordion';
import Accordions from './accordion';
import ErrorBoundary from "./Carousel";
class App extends Component {
constructor(props) {
super(props);
this.state = {
flag: undefined,
name: undefined,
nativeName:undefined,
callingCodes: undefined,
capital: undefined,
currencies:undefined,
languages: undefined,
region:undefined,
population:undefined,
alpha3Code:undefined,
isSearched: false,
subregion: undefined,
error: ""
}
}
getCity = async(e) => {
e.preventDefault();
const city = e.target.elements.cityname.value;
const api_call = await fetch(`https://restcountries.eu/rest/v2/name/${city}?fullText=true`);
const data = await api_call.json();
console.log(data);
this.setState({
flag: data[0].flag,
name: data[0].name,
nativeName: data[0].nativeName,
alpha3Code: data[0].alpha3Code,
callingCodes: data[0].callingCodes,
capital: data[0].capital,
currencies: data[0].currencies[0].name,
languages: data[0].languages[0].name,
region: data[0].region,
population: data[0].population,
subregion:data[0].subregion
});
}
toggleSearch = () => {
this.setState({
isSearched: true
})
}
render() {
let search;
if(this.state.isSearched) {
search =
<div className="content-1">
<div className="marginbottom">
<img className="flags" src={this.state.flag}/>
<h2><span className="bold">Name:</span> {this.state.name}</h2>
<div><span className="bold">Native Name:</span> {this.state.nativeName}</div>
<div><span className="bold">Abbreviation:</span> {this.state.alpha3Code}</div>
<div><span className="bold">Calling Code:</span> {this.state.callingCodes}</div>
<div><span className="bold">Capital: </span>{this.state.capital}</div>
<div><span className="bold">Currencies:</span> {this.state.currencies}</div>
<div><span className="bold">Language:</span> {this.state.languages}</div>
<div><span className="bold">Region: </span>{this.state.region}</div>
<div><span className="bold">Population:</span> {this.state.population}</div>
</div>
<Accordions name={this.state.name} population={this.state.population} subregion={this.state.subregion}/>
</div>
} else {
search=<p>Enter a valid country name</p>;
}
return (
<div className="App">
<header className="App-header">
<h1>Globe Search</h1>
<h5>Search For Cities Around the Globe</h5>
</header>
<div class="content">
<NavBar/>
<form
onSubmit={this.getCity} >
<input
placeholder="Enter Country"
type="text"
name="cityname"/>
<button onClick={this.toggleSearch} className="btn btn-success m-2">Search</button>
</form>
<div>
<div>{search}</div>
</div>
</div>
</div>
);
}
}
export default App;
Комментарии:
1. Если вы обернете всю свою
getCity
логику вtry
/catch
и выйдете из системы с ошибкой, что это скажет?2. Сообщает следующее: {статус: 404, сообщение: «Не найдено»} Ошибка типа: не удается прочитать свойство ‘flag’ undefined в _callee $ (App.js: 40) при tryCatch (runtime.js: 62) в Generator.invoke [как _invoke] (runtime.js: 288) в Generator.prototype.(: 3000 / анонимная функция) [как следующий] ( localhost: 3000/static/js/ 1.chunk.js :494:21 ) на этапе asyncgenerator (asyncToGenerator.js:3) на _next (asyncToGenerator.js:
3. Может быть, я ошибаюсь в этом, но ваша кнопка не отправляется, поэтому
this.getCity
никогда не вызывается, и состояние никогда не устанавливается в сторону отisSearched
значенияtrue
, установленного при нажатии кнопки. BecauseisSearched
изменено наtrue
, но остальная часть состояния остается неопределенной при повторном рендеринге,this.state.flag
а другие все еще не определены, поэтому система возвращает ошибку.4. Какая у вас версия React?
5. @Emidomenge React16
Ответ №1:
когда вы отправляете пустое значение или недопустимое место, вы получите ошибку, поскольку попытаетесь получить неизвестный URL. таким образом, вы можете проверить, является ли значение city пустым или нет, а также проверить ответ от api и соответствующим образом обновить состояние
getCity = async(e) => {
e.preventDefault();
const city = e.target.elements.cityname.value;
// check if input field is empty or not
if(city) {
const api_call = await fetch(`https://restcountries.eu/rest/v2/name/${city}?fullText=true`);
const data = await api_call.json();
console.log(data);
// check if value entered in input is valid
// so check api returns a valid response or not
if(data amp;amp; !data.status) {
this.setState({
isSearched: true,
flag: data[0].flag,
name: data[0].name,
nativeName: data[0].nativeName,
alpha3Code: data[0].alpha3Code,
callingCodes: data[0].callingCodes,
capital: data[0].capital,
currencies: data[0].currencies[0].name,
languages: data[0].languages[0].name,
region: data[0].region,
population: data[0].population,
subregion:data[0].subregion
});
} else {
this.setState({
isSearched:false
})
}
} else {
this.setState({
isSearched:false
})
}
}
А также измените кнопку на type="submit"
<button type="submit" className="btn btn-success m-2">Search</button>
toggleSearch
Метод не нужен
Все будет работать нормально
Ответ №2:
Сначала вам нужно изменить вашу кнопку на тип отправки, который называется <button type="submit" ...>
так this.getCity
. Если вам нужно isSearched
, вызовите его из this.getCity
или создайте новую функцию отправки handleSearch()
и поместите this.toggleSearch()
и this.getCity()
внутрь нее.
import React, { Component } from 'react';
import './App.css';
import NavBar from "./navbar";
import axios from "axios";
import Accordion from './accordion';
import Accordions from './accordion';
import ErrorBoundary from "./Carousel";
class App extends Component {
constructor(props) {
super(props);
this.state = {
flag: undefined,
name: undefined,
nativeName:undefined,
callingCodes: undefined,
capital: undefined,
currencies:undefined,
languages: undefined,
region:undefined,
population:undefined,
alpha3Code:undefined,
isSearched: false,
subregion: undefined,
error: ""
}
}
getCity = async(e) => {
e.preventDefault();
// Call toggleSearch somewhere in here if you really need it
this.toggleSearch();
const city = e.target.elements.cityname.value;
const api_call = await fetch(`https://restcountries.eu/rest/v2/name/${city}?fullText=true`);
const data = await api_call.json();
console.log(data);
this.setState({
flag: data[0].flag,
name: data[0].name,
nativeName: data[0].nativeName,
alpha3Code: data[0].alpha3Code,
callingCodes: data[0].callingCodes,
capital: data[0].capital,
currencies: data[0].currencies[0].name,
languages: data[0].languages[0].name,
region: data[0].region,
population: data[0].population,
subregion:data[0].subregion
});
}
toggleSearch = () => {
this.setState({
isSearched: true
})
}
render() {
let search;
if(this.state.isSearched) {
search =
<div className="content-1">
<div className="marginbottom">
<img className="flags" src={this.state.flag}/>
<h2><span className="bold">Name:</span> {this.state.name}</h2>
<div><span className="bold">Native Name:</span> {this.state.nativeName}</div>
<div><span className="bold">Abbreviation:</span> {this.state.alpha3Code}</div>
<div><span className="bold">Calling Code:</span> {this.state.callingCodes}</div>
<div><span className="bold">Capital: </span>{this.state.capital}</div>
<div><span className="bold">Currencies:</span> {this.state.currencies}</div>
<div><span className="bold">Language:</span> {this.state.languages}</div>
<div><span className="bold">Region: </span>{this.state.region}</div>
<div><span className="bold">Population:</span> {this.state.population}</div>
</div>
<Accordions name={this.state.name} population={this.state.population} subregion={this.state.subregion}/>
</div>
} else {
search=<p>Enter a valid country name</p>;
}
return (
<div className="App">
<header className="App-header">
<h1>Globe Search</h1>
<h5>Search For Cities Around the Globe</h5>
</header>
<div class="content">
<NavBar/>
<form
onSubmit={this.getCity} >
<input
placeholder="Enter Country"
type="text"
name="cityname"/>
{/* Removed onClick and added type="submit" */}
<button type="submit" className="btn btn-success m-2">Search</button>
</form>
<div>
<div>{search}</div>
</div>
</div>
</div>
);
}
}
export default App;
Ответ №3:
Выглядит как эта строка
const city = e.target.elements.cityname.value;
не получает ожидаемого значения. В результате вы получаете здесь неизвестный URL:
const api_call = await fetch(`https://restcountries.eu/rest/v2/name/${city}?fullText=true`);
Тогда все, что приведено ниже, не определено, и вы получаете такие ошибки.
Комментарии:
1. Как мне заставить его отображать сообщение типа
please enter valid city
вместо того, чтобы отображать страницу ошибки? Спасибо!2. @KennyQuach Одним из решений будет создание массива, содержащего все допустимые города, а затем проверка, соответствует ли переменная «city» элементу из вашего массива
Ответ №4:
import React, { Component } from 'react';
import './App.css';
class App extends Component {
constructor(props) {
super(props);
this.state = {
flag: undefined,
name: undefined,
nativeName:undefined,
callingCodes: undefined,
capital: undefined,
currencies:undefined,
languages: undefined,
region:undefined,
population:undefined,
alpha3Code:undefined,
isSearched: false,
subregion: undefined,
error: ""
}
}
getCity = async(e) => {
e.preventDefault();
const city = e.target.elements.cityname.value;
const api_call = await fetch(`https://restcountries.eu/rest/v2/name/${city}?fullText=true`);
api_call.json()
.then((data) => {
this.setState({
flag: data[0].flag,
name: data[0].name,
nativeName: data[0].nativeName,
alpha3Code: data[0].alpha3Code,
callingCodes: data[0].callingCodes,
capital: data[0].capital,
currencies: data[0].currencies[0].name,
languages: data[0].languages[0].name,
region: data[0].region,
population: data[0].population,
subregion:data[0].subregion,
error: ''
});
})
.catch((error) => {
this.setState({error})
})
}
toggleSearch = () => {
this.setState({
isSearched: true
})
}
render() {
let search;
if(this.state.isSearched amp;amp; this.state.error === '') {
search =
<div className="content-1">
<div className="marginbottom">
<img className="flags" src={this.state.flag}/>
<h2><span className="bold">Name:</span> {this.state.name}</h2>
<div><span className="bold">Native Name:</span> {this.state.nativeName}</div>
<div><span className="bold">Abbreviation:</span> {this.state.alpha3Code}</div>
<div><span className="bold">Calling Code:</span> {this.state.callingCodes}</div>
<div><span className="bold">Capital: </span>{this.state.capital}</div>
<div><span className="bold">Currencies:</span> {this.state.currencies}</div>
<div><span className="bold">Language:</span> {this.state.languages}</div>
<div><span className="bold">Region: </span>{this.state.region}</div>
<div><span className="bold">Population:</span> {this.state.population}</div>
</div>
</div>
} else {
search=<p>Enter a valid country name</p>;
}
return (
<div className="App">
<header className="App-header">
<h1>Globe Search</h1>
<h5>Search For Cities Around the Globe</h5>
</header>
<div class="content">
<form
onSubmit={this.getCity} >
<input
placeholder="Enter Country"
type="text"
name="cityname"/>
<button onClick={this.toggleSearch} className="btn btn-success m-2">Search</button>
</form>
<div>
<div>{search}</div>
</div>
</div>
</div>
);
}
}
export default App;