Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

177
Vistas
Storing data from Axios Promise for multiple uses

I have created an endpoint in express that handles get requests. From a react component, I make a get request to said endpoint using axios. I want to store the data in an object in my Component class so that it can be accessed at multiple times (onComponentDidLoad, multiple onClick event handlers, etc). Is there a way to store the data outside of the axios promise, and/or preserve the promise so that I can do multiple .then calls without the promise being fulfilled?

I have tried using setState(), returning the promise, and returning the actual data from the get request.

Here is what I have right now:

constructor {
  super();
  this.myData = [];
  
  this.getData = this.getData.bind(this);
  this.storeData = this.storeData.bind(this);
  this.showData = this.showData.bind(this);
}

// Store data
storeData = (data) => {this.myData.push(data)};

// Get data from API
getData() {
    axios
        .get('/someEndpoint')
        .then(response => {
            let body = response['data'];

            if(body) {
                this.storeData(body);
            }
        })
        .catch(function(error) {
            console.log(error);
        });
}

showData() {
    console.log(this.myData.length); // Always results in '0'
}

componentDidMount = () => {
    this.getData();   // Get data
    this.showData();   // Show Data
}
    
render() {
  return(
      <Button onClick={this.showData}> Show Data </Button>
  );
}

Edit I was incorrect in my question, storing the promise and then making multiple .then calls works. I had it formatted wrong when i tried it.

about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

If you just store the promise locally and access it as a promise it should work fine.

getData() {
  // if request has already been made then just return the previous request.
  this.data = this.data || axios.get(url)
  .then( response => response.data)
  .catch(console.log)
  return this.data
}

showData() {
  this.getData().then(d => console.log('my data is', data));
}
about 4 years ago · Juan Pablo Isaza Denunciar

0

This code won't quite work because you're attempting to show the data without waiting it to be resolved:

componentDidMount = () => {
    this.getData();
    this.showData();
}

As you hinted toward in your original post, you'll need to extract the data from the Promise and there's no way to do that in a synchronous manner. The first thing you can do is simply store the original Promise and access it when required - Promises can be then()ed multiple times:

class C extends React.Component {
  state = {
    promise: Promise.reject("not yet ready")
  };

  showData = async () => {
    // You can now re-use this.state.promise.
    // The caveat here is that you might potentially wait forever for a promise to resolve.
    console.log(await this.state.promise);
  }

  componentDidMount() {
    const t = fetchData();
    this.setState({ promise: t });
    // Take care not to re-assign here this.state.promise here, as otherwise
    // subsequent calls to t.then() will have the return value of showData() (undefined)
    // instead of the data you want.
    t.then(() => this.showData());
  }
  
  render() {
    const handleClick = () => {
      this.showData();
    };

    return <button onClick={handleClick}>Click Me</button>;
  }
}

Another approach would be to try to keep your component as synchronous as possible by limiting the asyncrony entirely to the fetchData() function, which may make your component a little easier to reason about:

class C extends React.Component {
  state = {
    status: "pending",
    data: undefined
  };

  async fetchData(abortSignal) {
    this.setState({ status: "pending" });
    try {
      const response = await fetch(..., { signal: abortSignal });
      const data = await response.json();
      this.setState({ data: data, status: "ok" });
    } catch (err) {
      this.setState({ error: err, status: "error" });
    } finally {
      this.setState({ status: "pending" });
    }
  }

  showData() {
    // Note how we now do not need to pollute showData() with asyncrony
    switch (this.state.status) {
      case "pending":
        ...
      case "ok":
        console.log(this.state.data);
      case "error":
        ...
    }
  }

  componentDidMount() {
    // Using an instance property is analogous to using a ref in React Hooks.
    // We don't want this to be state because we don't want the component to update when the abort controller changes.
    this.abortCtrl = new AbortController();
    this.fetchData(this.abortCtrl.signal);
  }

  componentDidUnmount() {
    this.abortCtrl.abort();
  }

  render() {
    return <button onClick={() => this.showData()}>Click Me</button>
  }
}
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda