I'm working on a simple project using react hooks, I want to update the state from fetched data from the api http://geoplugin.net/json.gp . However, when I try to update the state it's not working. Only the initial state is returned.
import React, { Fragment,useState,useEffect } from 'react';
import {container,Row,Table} from 'reactstrap';
import axios from 'axios';
function LiveVisitors() {
const [visitors,setVisitors] =useState([{
ip: '',
countryCode: '',
city: '',
state: '',
country: ''
}]);
const {ip,countryCode,city,state,country} = visitors;
useEffect(()=>{
getUserData()
},[])
//get user data
const getUserData = () =>{
const res= axios.get(`http://geoplugin.net/json.gp`).then(res =>{
// console.log(res)
const {geoplugin_request,
geoplugin_countryCode,
geoplugin_countryName,
geoplugin_city,
geoplugin_region
} =res.data;
const visitor = {
ip: geoplugin_request,
countryCode: geoplugin_countryCode,
city: geoplugin_city,
state: geoplugin_region,
country: geoplugin_countryName
};
setVisitors(visitors => [...visitors,visitor])
console.log(res.data)
console.log({visitor})
console.log(visitors)
}).catch (err =>{
console.log(err)
})
}
Your code works when you remove the axios part that is breaking the setState. I prepared an example for you that works and adds another visitor element.
https://codesandbox.io/s/react-playground-forked-hqswi?file=/index.js
import React, { Fragment, useState, useEffect } from "react";
import ReactDOM from "react-dom";
function LiveVisitors() {
const [visitors, setVisitors] = useState([
{
ip: "",
countryCode: "",
city: "Warsaw",
state: "",
country: "Poland"
},
{
ip: "",
countryCode: "",
city: "Gdańsk",
state: "",
country: "Poland"
}
]);
const { ip, countryCode, city, state, country } = visitors;
useEffect(() => {
getUserData();
}, []);
const getUserData = () => {
//imitate fetch
setVisitors([
...visitors,
{
ip: "",
countryCode: "",
city: "Wrocław",
state: "",
country: "Poland"
}
]);
};
return (
<div>
{visitors.map((el) => (
<div>{el.city}</div>
))}
</div>
);
}
const wrapper = document.getElementById("container");
ReactDOM.render(<LiveVisitors />, wrapper);
By using useEffect
with an empty array at the end you force it to run only once
Try
useEffect(()=>{
getUserData()
},[visitors]);
or without the array
useEffect(()=>{
getUserData()
});
it should trigger every time React detects a change, hope that helps.
Here is a really good article that gives a good explanation.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.