useEffect render previous value, instead new setState

30 Views Asked by At

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])

0

There are 0 best solutions below