Home > Software design >  Why are state values ​returning undefined? with reactjs
Why are state values ​returning undefined? with reactjs

Time:04-30

const [value, setValue]=useState();

 useEffect(() => {
    authService.getAddr().then((response) => {
      setndata(response.data);
    },
      (error) => {
        console.log(error);
      }
    );
   ndata.filter((obj) => obj._id === dataidM).map((data) => setValue(data.AddressTitle));
  }, [dataidM, ndata]);

  const [formData, setFormData] = useState({
    billingAddr: false,
    shippingAddr: false,
    AddressTitle:`Hello, ${value} !`   **// value is undefined**
  });

   return  (
   <div>  ......
     <div className='bg-info'>
       {dataidM} --- {ndata.filter((obj) => obj._id === dataidM).map((data) => { return 
       data.AddressTitle })} -- --{value} 
     </div>   **//I can see the values ​​as I want here when I check**
  </div>
) 

Why is it returning undefined in the other place, how can I show this value there? By default it should appear.

CodePudding user response:

To connect the variables you need to add an effect like so:

useEffect(() => {
   setFormData({
    billingAddr: false,
    shippingAddr: false,
    AddressTitle:`Hello, ${value} !`
  });
}, [value]);

This way every time value changes formData will change with it.

*a good note is that it is not recommended to use variables like so and just use Hello, ${value} ! in the rendering instead of a new variable.

More details as to why it was undefined:

const [formData, setFormData] = useState({
    billingAddr: false,
    shippingAddr: false,
    AddressTitle:`Hello, ${value} !`   **// value is undefined**
  });

Here you set the default of the value and this default uses the default value, which is undefined as you set it here:

const [value, setValue]=useState(/*Here empty means undefined*/);

CodePudding user response:

setState actions are asynchronous and are batched for performance gains. This is explained in the documentation of setState.

setState() does not immediately mutate this.state but creates a pending state transition. Accessing this.state after calling this method can potentially return the existing value. There is no guarantee of synchronous operation of calls to setState and calls may be batched for performance gains.

Below code might not execute like you expected.

useEffect(() => {
  authService.getAddr().then(
    (response) => {
      setndata(response.data);
    },
    (error) => {
      console.log(error);
    }
  );
  ndata
    .filter((obj) => obj._id === dataidM)
    .map((data) => setValue(data.AddressTitle));
}, [dataidM, ndata]);

You are making an asynchronous request and updating the value without waiting for the response itself. I just modified your code like below. Test and let me know if you find any issues.

useEffect(() => {
  const api = async () => {
    try {
      const response = await authService.getAddr();
      setndata(response?.data);
      response.data
        ?.filter((obj) => obj._id === dataidM)
        .map((data) => setValue(data.AddressTitle));
    } catch (error) {
      console.log(error);
    }
  };
  api();
}, [dataidM, ndata]);

As @Mihail Vratchanski suggested, it's always good to initialize state values with a default value.

  • Related