jrz
jrz

Reputation: 1417

Rendering fetched data to screen

I built a component which uses Axios get request and retrieves a list of email addresses.

I don't know what should I write inside render() so I will be able to see the emails list over my website.

This is my suggestion:

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import {Link} from "react-router";
import axios from 'axios';

export class GetEmailsComponent extends Component {

state = {
    emails: []
}

componentDidMount(){
    //this.setState({emailList : undefined});
    axios.get('./api/EmailAddresses')
        .then(response => {
            this.setState({emails: response.data});
            console.log(response.data);
        }).catch(function (error) {
            console.log(error);
        });
}

render() { 
      return (
        <div>
            <button type = "button" onClick= {this.state.emails.map(email => <div>{email}</div>)}>GET ALL EMAILS</button>
        </div>
    );
  }
}

When I check the Console I see an array of the desired emails. I am looking for a suggestion of how to edit my code so it will render all this mails to the screen (After the button clicked).

Thanks is advance.

Upvotes: 1

Views: 161

Answers (3)

Amila Dulanjana
Amila Dulanjana

Reputation: 1914

You have used a componentDidMount life cycle in react to fetch the data. And you called that method via a button. Normally we are not calling life cycle methods like this. i think its better to read the react documentation doc for get an idea about life cycles.

You can declare a function and can call that function via a button. Please find below answer.

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      emails: [],
      showEmails:false,
    };
  }

  componentDidMount () {
    axios
    .get("./api/EmailAddresses")
    .then(response => {
       this.setState({ emails: response.data });
       console.log(response.data);
    })
  .catch(function(error) {
    console.log(error);
  });
}

render() {
   return (
     <div>
       <button type="button" onClick={() => this.setState({showEmail:true})}>
         Get all mails
       </button>
       {this.state.showEmail && this.state.emails.map(email => <div>{email}</div>)}
     </div>
   );
 }
}

Upvotes: 1

Hemadri Dasari
Hemadri Dasari

Reputation: 34014

Change your code to something like below.

You need to get emails when button is clicked so you need have custom event handler function for that but not componentDidMount method. You cannot call componentDidMount method as event handler function.

Also when you render emails in loop you need to set unique key to top element inside loop. Key can be a index or unique id from data. Looks like you don’t have unique id from emails array so you can use index as key like below

     import React, { Component } from 'react';
     import PropTypes from 'prop-types';
     import {Link} from "react-router";
     import axios from 'axios';

     export class GetEmailsComponent extends Component {

     state = {
        emails: []
     }

  getEmails = () =>{
       //this.setState({emailList : undefined});
       axios.get('./api/EmailAddresses')
         .then(response => {
             this.setState({emails: response.data});
             console.log(response.data);
         }).catch(function (error) {
            console.log(error);
        });
    }

     render() { 
           return (
                <div>
                    <ul>
                      {this.state.emails.map((email, index)=> <li key={"Key-"+index}>{email}</li>)}
                     </ul>
                    <button type="button" onClick={()=> this.getEmails()}>Get all mails</button>
                </div>
                 )
            }
         }

Upvotes: 0

Gilad Bar
Gilad Bar

Reputation: 1342

Inside your render method, you can map over this.state.emails and return an element for each email (At first the array will be empty, so maybe you can add a condition so you wouldn't render an empty div for no reason) Something like:

render() {
    return (
        <div>
            {this.state.emails.map(email => <div>{email}</div>)}
        </div>
    );
}

As for componentDidMount - It's a lifecycle method of React. Anything you put there will run after the component mounts for the first time. If you want to trigger the call to Axios once the button is clicked, define a different function (like fetchEmails) and call it using this.fetchEmails.

Upvotes: 3

Related Questions