Получение ошибки в Reactjs. Он говорит о необработанном отклонении (TypeError). Но я уже сказал ему, что делать, если пользователь вводит недопустимое имя во входных данных

#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 , установленного при нажатии кнопки. Because isSearched изменено на 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;