Enguias
Enguias

Reputation: 73

Why is my function in React being called twice but not equaly executed?

This is my function in my home.js React App, with all the needed logs:

function pin(){
  console.log('function pin()');
  var result = []
  var url = "http://warm-hamlet-63390.herokuapp.com/pin/list"
  axios.get(url)
  .then((res)=>{
    console.log('after .then');
    if(res.data){
      console.log('inside pin() if');
      for(var i in res.data.data)
      {
          result.push([i, res.data.data[i]])
      }
    }
    console.log('after pin() if');
  })
  console.log('end of pin()');
  return result;
}

Immediately after the function, I have my exported function that renders the page:

export default function App(){
  const{isLoaded, loadError} = useLoadScript({
    googleMapsApiKey: "my_api_key",
    libraries,
  })

  const [markers, setMarkers] = React.useState([]);
  if(loadError) return "Erro a carregar o mapa"
  if(!isLoaded) return "Carregando"

  return <div>
    {pin()}
    <GoogleMap 
    mapContainerStyle={mapContainerStyle} 
    zoom={11} 
    center={center}
    >
    <Marker
      position={
        {
           lat: 2, 
           lng:2
        }
      }
      icon={nivelpin.verde}
    >
    </Marker>

    </GoogleMap>
    
  </div>
}

The JSON file that the URL is being set to has 7 records in it, but as you can see in the image, it's being executd twice.

The function is only executing twice inside the .then((res)=>{

Why is that? Is it something to do with axios?

Image: https://media.discordapp.net/attachments/656598463638798357/852982191029747732/unknown.png

EDIT: Added the logs and the function App() + Image that shows the logs:

https://media.discordapp.net/attachments/656598463638798357/852995551691276368/unknown.png

Upvotes: 1

Views: 1084

Answers (1)

drrkmcfrrk
drrkmcfrrk

Reputation: 368

You're calling a function in the template that is returned. Meaning that function is going to get called on every render.

You have to store the results to a variable which gets rendered in your component. Something like this:

class App extends Component {
  constructor() {
    super();
    this.state = { data: [] };
  }

  componentDidMount() {
    fetch(`https://api.coinmarketcap.com/v1/ticker/?limit=10`)
      .then(res => res.json())
      .then(json => this.setState({ data: json }));
  }

  render() {
    return (
      <div>
        <ul>
          {this.state.data.map(el => (
            <li>
              {el.name}: {el.price_usd}
            </li>
          ))}
        </ul>
      </div>
    );
  }
}

(source)

OR if you want to stick with a functional component:

function App() {
  const [data, setData] = useState({ hits: [] });
 
  useEffect(async () => {
    const result = await axios(
      'https://hn.algolia.com/api/v1/search?query=redux',
    );
 
    setData(result.data);
  });
 
  return (
    <ul>
      {data.hits.map(item => (
        <li key={item.objectID}>
          <a href={item.url}>{item.title}</a>
        </li>
      ))}
    </ul>
  );
}
 
export default App;

(source)

Upvotes: 2

Related Questions