Im trying to set set an IP address into "" and (last queried value). But its always render same state and render new state after second render. I know its because of setState syncronomous behaviour. I have been trying to put timeout and declare indirect value to make it works, but none of these succeed.
**///DECLARED VALUE/////**
const [ip, setIp] = useState("");
const [isValid, setIsValid] = useState(true);
const [buttonActive, setButtonActive] = useState(false);
const [ipV4Completed, setIpV4Completed] = useState(false);
const [savedIp, setSavedIp] = useState("");
const [location, setLocation] = useState("");
const [isp, setIsp] = useState("");
const [ipV4, setIpV4] = useState(true);
const [savedData, setSavedData] = useState("")
let storageData = JSON.parse(localStorage.getItem("savedData")) || [];
const onInputChange = (data) => {
setIp(data.target.value);
validateInput(data);
};
const validateInput = (e) => {
const ipV4Regex = /^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}$/;
const ipV6Regex = /^([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}$/i;
let { value } = e.target;
if (value.match(ipV4Regex)) {
setIsValid(true);
setButtonActive(true);
setIpV4(true);
} else if (value.match(ipV6Regex)) {
setIsValid(true);
setButtonActive(true);
setIpV4(false);
} else if (value === "") {
setIsValid(true);
setButtonActive(false);
} else {
setIsValid(false);
setButtonActive(false);
}
};
**///FUNCTION THAT RETURN SUPPOSED VALUE/////**
const proceedInput = useCallback(() => {
console.log('proceedInput called with ip:', ip);
axios
.get(
`https://geo.ipify.org/api/v2/country,city?apiKey=${process.env.REACT_APP_KEY_APIFY}&ipAddress=${ip}`)
.then((response) => {
setSavedIp(response.data.ip);
setLocation(response.data.location);
setMapLocation(response.data.location);
setIsp(response.data.isp);
const ipExist = storageData.some(item => item.ip === response.data.ip);
if (!ipExist) {
storageData.push(response.data);
setSavedData(storageData);
}
if (ipV4) {
setIpV4Completed(true);
} else {
setIpV4Completed(false);
};
})
.catch((error) => {
console.error("Failed to fetch location data:", error);
});
}, [ip]);
**///BLOCK WHERE USESTATE NOT DIRECTLY UPDATED/////**
useEffect(() => {
if (currentLocation){
setIp("")
proceedInput();
}
}, [currentLocation])
**///BLOCK WHERE USESTATE NOT DIRECTLY UPDATED/////**
useEffect(() => {
if (historyLocation){
setIp(historyLocation.ip)
proceedInput();
}
}, [historyLocation])
useEffect(() => {
if (savedData){
localStorage.setItem("savedData", JSON.stringify(savedData));
}
}, [savedData])