[英]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.