挂钩调用无效。如何使用 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>
);
}
我有这个 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>
);
}