挂钩调用无效。如何使用 react axios get call 设置一个值?

Invalid hook call. How to set a value with react axios get call?

我有这个 React 组件,它有一个简单的形式,当你输入超级英雄的名字时,它会向 API 发出 axios get 请求,该 json 对象成功响应,信息为英雄说。该信息存储在状态中,然后映射以创建网格。它曾经作为 class 元素工作得很好所以我开始做应用程序的其他部分与这部分无关,但是当我再次 运行 整个应用程序所以检查我得到一个钩子此组件调用错误。

这是导引头组件,我做了class和功能版。

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 = () => {
   const fetchData = (data) => {axios.get(`https://www.superheroapi.com/api.php/1589015884770221/search/${name}`)
       .then((response) => {
           localStorage.setItem("addHeroAction", true);
           let results = response.data.results;
           localStorage.setItem("matchedHeros", results);
       }).catch((error) => {
           console.log(error)
       })
   }

   let matchedHeros = localStorage.getItem("matchedHeros") ? localStorage.getItem("matchedHeros") : [];
   
   const gridRender = (response) =>{
       if(response.length && response != undefined){
           console.log(response)
           return( 
           <div className="grid__background">
           <div className="grid">
               <div className="grid__box grid__top grid__top--container"></div>
               <div className="grid__box grid__top grid__top--container"><h2>Name</h2></div>
               <div className="grid__box grid__top grid__top--container"><h2>Intelligence</h2></div>
               <div className="grid__box grid__top grid__top--container"><h2>Strenght</h2></div>
               <div className="grid__box grid__top grid__top--container"><h2>Speed</h2></div>
               <div className="grid__box grid__top grid__top--container"><h2>Durability</h2></div>
               <div className="grid__box grid__top grid__top--container"><h2>Power</h2></div>
               <div className="grid__box grid__top grid__top--container"><h2>Combat</h2></div>
               <div className="grid__box grid__top grid__top--container"></div>
               {response.map(hero => grid(hero, hero.id))}
           </div>
           </div>)
       } else {
           return (<div></div>)
       }
   }

   return (
       <div>
           <h1>Find your next teammate!</h1>
               <Formik
               initialValues={{ name: ''}}
               validate={values => {
                   const errors = {};
                   if (!values.name) {
                       errors.name = 'Required';
                   } else if (
                       !/^[a-zA-Z]*$/.test(values.name)
                   ) {
                       errors.name = 'Invalid name';
                   }
                   return errors;
               }}
               onSubmit={(values) => {
                   console.log(fetchData(values.name));
               }}
               >
               {() => (
                   <Form>
                   <Field type="text" name="name" />
                   <ErrorMessage name="name" component="div" />
                   <button type="submit">
                       Submit
                   </button>
                   </Form>
               )}
               </Formik>
                   {gridRender(matchedHeros)}
       </div>
       )
   } */


   class Seeker extends React.Component{
   state = {
       matchedHeros : [],
       loadingData : true
   }
   constructor(){
       super();
       this.fetchData = this.fetchData.bind(this);
   }

   
   fetchData = async (name) => {
       if(this.state.loadingData){
           await axios.get(`https://www.superheroapi.com/api.php/1589015884770221/search/${name}`)
           .then((response) => {
               localStorage.setItem("addHeroAction", true);
               this.setState({matchedHeros : response.data.results, loadingData : false});
           }).catch((error) => {
               console.log(error)
           })
       }
  
       
   }     

   
   render(){
       return (
           <div>
               <h1>Find your next teammate!</h1>
                   <Formik
                   initialValues={{ name: ''}}
                   validate={values => {
                       const errors = {};
                       if (!values.name) {
                           errors.name = 'Required';
                       } else if (
                           !/^[a-zA-Z]*$/.test(values.name)
                       ) {
                           errors.name = 'Invalid name';
                       }
                       return errors;
                   }}
                   onSubmit={(values) => {
                       this.fetchData(values.name);
                   }}
                   >
                   {() => (
                       <Form>
                       <Field type="text" name="name" />
                       <ErrorMessage name="name" component="div" />
                       <button type="submit">
                           Submit
                       </button>
                       </Form>
                   )}
                   </Formik>
                   {console.log(this.state.matchedHeros)}
                   {this.state.matchedHeros.length ?  
                       (
                       <div className="grid__background">
                           <div className="grid">
                               <div className="grid__box grid__top grid__top--container"></div>
                               <div className="grid__box grid__top grid__top--container"><h2>Name</h2></div>
                               <div className="grid__box grid__top grid__top--container"><h2>Intelligence</h2></div>
                               <div className="grid__box grid__top grid__top--container"><h2>Strenght</h2></div>
                               <div className="grid__box grid__top grid__top--container"><h2>Speed</h2></div>
                               <div className="grid__box grid__top grid__top--container"><h2>Durability</h2></div>
                               <div className="grid__box grid__top grid__top--container"><h2>Power</h2></div>
                               <div className="grid__box grid__top grid__top--container"><h2>Combat</h2></div>
                               <div className="grid__box grid__top grid__top--container"></div>
                           </div>
                       </div>
                       )
                       :
                       <div></div>
                   }
                   {this.state.matchedHeros.map(hero => grid(hero, hero.id))}
           </div>
           )
   }
} 


export default Seeker; 

它使用 formik 库验证值,并将信息映射到 Grid 组件,该组件本身运行良好,因此问题出在该组件中。 axios 调用还在 localStorage 中设置了一个值,我需要在单击按钮时设置该值。

原来是 class 组件,但有了它我在控制台上出现了这个错误。

“未捕获错误:挂钩调用无效。挂钩只能在函数组件的主体内部调用。”

然后我做了功能组件版本,在上面的代码中有注释,但是用它我无法用axios更新状态。

当我查看其他人的示例时,它们看起来像我的,但我仍然遇到挂钩调用错误,我已经检查过我有最新版本的 React,所以这不是问题所在。 我究竟做错了什么?或者,你们能给我什么建议来达到同样的结果?

如果您想在组件初始挂载时获得英雄:

import React, { useState, useEffect } from "react";

async function getHeros(name) {
    return axios.get(
        `https://www.superheroapi.com/api.php/1589015884770221/search/${name}`
    );
}

const Seeker = () => {
    const [heros, setHeros] = useState([]);

    useEffect(() => {
        getHeros('someName').then((heros) => {
            console.log('heros: ', heros);
            setHeros(heros);
            localStorage.setItem("matchedHeros", heros);
        }, console.error);
    }, []);

    return (
        <div>
            {heros.map((hero, i) => (
                <span>{hero}</span>
            ))}
        </div>
    );
}