javascript - node - react async methods
Use Async/Await con Axios en React.js (2)
Dos cuestiones saltan:
Su
getData
nunca devuelve nada, por lo que su promesa (las funcionesasync
siempre devuelven una promesa) se resolverá conundefined
cuando se resuelvaEl mensaje de error muestra claramente que está intentando representar directamente la promesa que devuelve
getData
, en lugar de esperar a que se resuelva y luego la resolución
Direccionamiento # 1: getData
debe devolver el resultado de llamar a json
:
async getData(){
const res = await axios(''/data'');
return await res.json();
}
Addressig # 2: Tendríamos que ver más de tu código, pero fundamentalmente, no puedes hacer
<SomeElement>{getData()}</SomeElement>
... porque eso no espera la resolución. En su lugar, necesitarías usar getData
para establecer el estado:
this.getData().then(data => this.setState({data}))
.catch(err => { /*...handle the error...*/});
... y usa ese estado al renderizar:
<SomeElement>{this.state.data}</SomeElement>
Actualización : ahora que nos has mostrado tu código, deberías hacer algo como esto:
class App extends React.Component{
async getData() {
const res = await axios(''/data'');
return await res.json(); // (Or whatever)
}
constructor(...args) {
super(...args);
this.state = {data: null};
}
componentDidMount() {
if (!this.state.data) {
this.getData().then(data => this.setState({data}))
.catch(err => { /*...handle the error...*/});
}
}
render() {
return (
<div>
{this.state.data ? <em>Loading...</em> : this.state.data}
</div>
);
}
}
Otra actualización: Usted ha indicado una preferencia por usar await
en componentDidMount
en lugar de then
y catch
. Haría eso anidando una función async
IIFE dentro de ella y asegurándose de que esa función no se pueda lanzar. ( componentDidMount
sí no puede ser async
, nada consumirá esa promesa). Por ejemplo:
class App extends React.Component{
async getData() {
const res = await axios(''/data'');
return await res.json(); // (Or whatever)
}
constructor(...args) {
super(...args);
this.state = {data: null};
}
componentDidMount() {
if (!this.state.data) {
(async () => {
try {
this.setState({data: await this.getData()});
} catch (e) {
//...handle the error...
}
})();
}
}
render() {
return (
<div>
{this.state.data ? <em>Loading...</em> : this.state.data}
</div>
);
}
}
Siguiendo
Cómo usar async / await con axios en reaccionar.
Estoy intentando hacer una solicitud de obtención simple a mi servidor usando Async / Await en una aplicación React.js. El servidor carga un JSON simple en /data
que se ve así
JSON
{
id: 1,
name: "Aditya"
}
Puedo obtener los datos para mi aplicación React utilizando el método simple jquery ajax get. Sin embargo, quiero hacer uso de la biblioteca de axios y Async / Await para seguir los estándares ES7. Mi código actual se ve así:
class App extends React.Component{
async getData(){
const res = await axios(''/data'');
console.log(res.json());
}
render(){
return(
<div>
{this.getData()}
</div>
);
}
}
Usando este enfoque obtengo el siguiente error:
Los objetos no son válidos como hijo React (encontrado: [promesa de objeto]). Si querías representar una colección de hijos, usa una matriz en su lugar.
¿No lo estoy implementando correctamente?
En mi experiencia en los últimos meses, me he dado cuenta de que la mejor manera de lograr esto es:
class App extends React.Component{
constructor(){
super();
this.state = {
serverResponse: ''''
}
}
componentDidMount(){
this.getData();
}
async getData(){
const res = await axios.get(''url-to-get-the-data'');
const { data } = await res;
this.setState({serverResponse: data})
}
render(){
return(
<div>
{this.state.serverResponse}
</div>
);
}
}
Si está intentando realizar una solicitud posterior en eventos como un clic, llame a la función getData()
en el evento y reemplace el contenido de la misma manera:
async getData(username, password){
const res = await axios.post(''url-to-post-the-data'', {
username,
password
});
...
}
Además, si está realizando una solicitud cuando el componente está a punto de cargarse, simplemente reemplace async getData()
con async componentDidMount()
y cambie la función de representación de la siguiente manera:
render(){
return (
<div>{this.state.serverResponse}</div>
)
}