簡體   English   中英

無效的掛鈎調用。 如何通過反應 axios 來設置值?

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

I have this react component that has a simple form where, when you put a superhero name, it makes an axios get request to an API that responds successfully with json object with info of said hero. 該信息存儲在 state 中,然后通過映射創建一個網格。 它曾經作為 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 組件,但我在控制台上有這個錯誤。

“未捕獲的錯誤:無效的掛鈎調用。掛鈎只能在 function 組件的主體內部調用。”

然后我制作了功能組件版本,該版本在上面的代碼中進行了注釋,但使用它我無法使用 axios 更新 state。

當我查看其他人的示例時,它們看起來像我的,但我仍然遇到鈎子調用錯誤,我已經檢查過我有最新版本的 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>
    );
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM