Неверный вызов крючка. Как задать значение с помощью вызова react axios get?

#javascript #reactjs #react-hooks #axios #state

#язык JavaScript #реагирует на #реагируют-крючки #аксиос #государство

Вопрос:

У меня есть компонент react, который имеет простую форму, в которой, когда вы вводите имя супергероя, он отправляет запрос axios get в API, который успешно отвечает объектом json с информацией об указанном герое. Эта информация хранится в состоянии, а затем отображается для создания сетки. Раньше он отлично работал как элемент класса, поэтому я начал выполнять другие части приложения, которые не имеют ничего общего с этой частью, но когда я снова запускаю все приложение, поэтому проверьте, что я получаю ошибку вызова в этом компоненте.

Это компонент искателя, я сделал версию класса и функции.

 import React, { useState } from "react"; import { Formik, Form, Field, ErrorMessage } from 'formik'; import axios from "axios"; require("babel-core/register"); require("babel-polyfill"); import grid from "../components/grid";   /*  const Seeker = () =gt; {  const fetchData = (data) =gt; {axios.get(`https://www.superheroapi.com/api.php/1589015884770221/search/${name}`)  .then((response) =gt; {  localStorage.setItem("addHeroAction", true);  let results = response.data.results;  localStorage.setItem("matchedHeros", results);  }).catch((error) =gt; {  console.log(error)  })  }   let matchedHeros = localStorage.getItem("matchedHeros") ? localStorage.getItem("matchedHeros") : [];    const gridRender = (response) =gt;{  if(response.length amp;amp; response != undefined){  console.log(response)  return(   lt;div className="grid__background"gt;  lt;div className="grid"gt;  lt;div className="grid__box grid__top grid__top--container"gt;lt;/divgt;  lt;div className="grid__box grid__top grid__top--container"gt;lt;h2gt;Namelt;/h2gt;lt;/divgt;  lt;div className="grid__box grid__top grid__top--container"gt;lt;h2gt;Intelligencelt;/h2gt;lt;/divgt;  lt;div className="grid__box grid__top grid__top--container"gt;lt;h2gt;Strenghtlt;/h2gt;lt;/divgt;  lt;div className="grid__box grid__top grid__top--container"gt;lt;h2gt;Speedlt;/h2gt;lt;/divgt;  lt;div className="grid__box grid__top grid__top--container"gt;lt;h2gt;Durabilitylt;/h2gt;lt;/divgt;  lt;div className="grid__box grid__top grid__top--container"gt;lt;h2gt;Powerlt;/h2gt;lt;/divgt;  lt;div className="grid__box grid__top grid__top--container"gt;lt;h2gt;Combatlt;/h2gt;lt;/divgt;  lt;div className="grid__box grid__top grid__top--container"gt;lt;/divgt;  {response.map(hero =gt; grid(hero, hero.id))}  lt;/divgt;  lt;/divgt;)  } else {  return (lt;divgt;lt;/divgt;)  }  }   return (  lt;divgt;  lt;h1gt;Find your next teammate!lt;/h1gt;  lt;Formik  initialValues={{ name: ''}}  validate={values =gt; {  const errors = {};  if (!values.name) {  errors.name = 'Required';  } else if (  !/^[a-zA-Z]*$/.test(values.name)  ) {  errors.name = 'Invalid name';  }  return errors;  }}  onSubmit={(values) =gt; {  console.log(fetchData(values.name));  }}  gt;  {() =gt; (  lt;Formgt;  lt;Field type="text" name="name" /gt;  lt;ErrorMessage name="name" component="div" /gt;  lt;button type="submit"gt;  Submit  lt;/buttongt;  lt;/Formgt;  )}  lt;/Formikgt;  {gridRender(matchedHeros)}  lt;/divgt;  )  } */    class Seeker extends React.Component{  state = {  matchedHeros : [],  loadingData : true  }  constructor(){  super();  this.fetchData = this.fetchData.bind(this);  }     fetchData = async (name) =gt; {  if(this.state.loadingData){  await axios.get(`https://www.superheroapi.com/api.php/1589015884770221/search/${name}`)  .then((response) =gt; {  localStorage.setItem("addHeroAction", true);  this.setState({matchedHeros : response.data.results, loadingData : false});  }).catch((error) =gt; {  console.log(error)  })  }      }      render(){  return (  lt;divgt;  lt;h1gt;Find your next teammate!lt;/h1gt;  lt;Formik  initialValues={{ name: ''}}  validate={values =gt; {  const errors = {};  if (!values.name) {  errors.name = 'Required';  } else if (  !/^[a-zA-Z]*$/.test(values.name)  ) {  errors.name = 'Invalid name';  }  return errors;  }}  onSubmit={(values) =gt; {  this.fetchData(values.name);  }}  gt;  {() =gt; (  lt;Formgt;  lt;Field type="text" name="name" /gt;  lt;ErrorMessage name="name" component="div" /gt;  lt;button type="submit"gt;  Submit  lt;/buttongt;  lt;/Formgt;  )}  lt;/Formikgt;  {console.log(this.state.matchedHeros)}  {this.state.matchedHeros.length ?   (  lt;div className="grid__background"gt;  lt;div className="grid"gt;  lt;div className="grid__box grid__top grid__top--container"gt;lt;/divgt;  lt;div className="grid__box grid__top grid__top--container"gt;lt;h2gt;Namelt;/h2gt;lt;/divgt;  lt;div className="grid__box grid__top grid__top--container"gt;lt;h2gt;Intelligencelt;/h2gt;lt;/divgt;  lt;div className="grid__box grid__top grid__top--container"gt;lt;h2gt;Strenghtlt;/h2gt;lt;/divgt;  lt;div className="grid__box grid__top grid__top--container"gt;lt;h2gt;Speedlt;/h2gt;lt;/divgt;  lt;div className="grid__box grid__top grid__top--container"gt;lt;h2gt;Durabilitylt;/h2gt;lt;/divgt;  lt;div className="grid__box grid__top grid__top--container"gt;lt;h2gt;Powerlt;/h2gt;lt;/divgt;  lt;div className="grid__box grid__top grid__top--container"gt;lt;h2gt;Combatlt;/h2gt;lt;/divgt;  lt;div className="grid__box grid__top grid__top--container"gt;lt;/divgt;  lt;/divgt;  lt;/divgt;  )  :  lt;divgt;lt;/divgt;  }  {this.state.matchedHeros.map(hero =gt; grid(hero, hero.id))}  lt;/divgt;  )  } }    export default Seeker;    

Он использует библиотеку formik для проверки значений, и он сопоставляет информацию с компонентом сетки, который отлично работает сам по себе, поэтому проблема в этом компоненте. Вызов axios также устанавливает значение в localStorage, которое мне нужно установить при нажатии кнопки.

Оригиналом был компонент класса, но с ним у меня эта ошибка на консоли.

«Неперехваченная ошибка: Недопустимый вызов соединения. Крючки могут вызываться только внутри тела функционального компонента.»

Затем я создал версию функционального компонента, которая прокомментирована в приведенном выше коде, но с ее помощью я не могу обновить состояние с помощью axios.

Когда я смотрю на чужие примеры, они выглядят как мои, но я все равно получаю ошибку вызова крючка, я уже проверил, что у меня есть обновленные версии react, так что это не проблема. Что я делаю не так? или еще, что вы, ребята, можете мне посоветовать, чтобы добиться того же результата?

Ответ №1:

Если вы хотите получить героев при первоначальном монтаже компонента:

 import React, { useState, useEffect } from "react";  async function getHeros(name) {  return axios.get(  `https://www.superheroapi.com/api.php/1589015884770221/search/${name}`  ); }  const Seeker = () =gt; {  const [heros, setHeros] = useState([]);   useEffect(() =gt; {  getHeros('someName').then((heros) =gt; {  console.log('heros: ', heros);  setHeros(heros);  localStorage.setItem("matchedHeros", heros);  }, console.error);  }, []);   return (  lt;divgt;  {heros.map((hero, i) =gt; (  lt;spangt;{hero}lt;/spangt;  ))}  lt;/divgt;  ); }  

Комментарии:

1. Спасибо за вашу помощь! это действительно работает, но не для той цели, которую я искал. Как я могу сделать это таким образом, чтобы при отправке имени героя (которое написано пользователем во входных данных) вызов getHeros получал значение и выполнял поиск с его помощью? Потому что, если я попытаюсь поместить вызов useEffect в другую функцию, а затем вызвать указанную функцию, когда я отправлю форму, я получу ту же ошибку от formik, который вводит недопустимые вызовы крючков.

2. Эффект использования находится в корне компонента, а не внутри произвольных функций. Его основное применение-в качестве дескрипторов жизненного цикла при первоначальном монтаже компонента или при его обновлении. Здесь [] в конце эффекта использования делает его похожим на ‘componentDidMount для компонентов на основе классов. Чтобы выполнить то, что вы хотите, вам следует поискать в Google «получение данных при отправке реакции» для некоторых примеров кода. Хотя, я думаю, вам больше всего помогло бы посмотреть один или два урока на YouTube для создания простого проекта react.