1

i am working on project in which i have two input fields and submit button.When i click submit data from both fields store in a variable.Now i want to perform some function on this data As shown in my code.

Vanilla javascript code perfectly fine.But facing problem in React js

 var el=document.getElementById("button");

if(el)
{
el.addEventListener("click", function(max,min)
{

    const max1=document.getElementById("max").value;
    const min1=document.getElementById("min").value;

    const colors=['#000000', '#0004BF', '#0008FF', '#0140FF', '#0080FF', '#03BFFF', '#02FBFF', '#41FBBF', '#81FC81', '#BFFD41', '#FFFF00', '#FFBF01', '#FF8001', '#FF4000', '#BF2500', '#801500', '#FFFFFF']
    const n=16;
    var v=[];

    var  lmin = Math.log(min1);
    var  lmax = Math.log(max1);
    var delta = (lmax-lmin)/(n-1);
    for(let i = 1;i<16  ;i++)
    {
        let obj={}
        obj.key2=Math.exp(lmin+delta*(i-1)).toFixed(2);
        obj.key1=Math.exp(lmin+delta*((i+1)-1)).toFixed(2)
        obj.value=colors[i];
    
        v.push(obj);
    
    }
    console.log(v)
  
print(v);
 }
)}

Below React js code.I want to implement same code in react as i implement in simple js.

  const maxFreq = useRef();
const [val,setVal] = useState([])

const [obj,setObj]=useState({key1:0,key2:0:value:""});
const minFreq = useRef();
const colors=['#000000', '#0004BF', '#0008FF', '#0140FF', '#0080FF', '#03BFFF', '#02FBFF', '#41FBBF', '#81FC81', '#BFFD41', '#FFFF00', '#FFBF01', '#FF8001', '#FF4000', '#BF2500', '#801500', '#FFFFFF']

const handleClick=(e)=>{
    e.preventDefault();
         const min1=maxFreq.current.value;
         const max1=minFreq.current.value;
         const lmin = Math.log(min1);
         const  lmax = Math.log(max1);
         let delta = (lmax-lmin)/(n-1);
        
         for(let i = 1;i<16  ;i++)
         {
             
             var key11=Math.exp(lmin+delta*(i-1)).toFixed(2);
             var key21=Math.exp(lmin+delta*((i+1)-1)).toFixed(2)
             let value1=colors[i];
             
            // console.log(`key1:${key11}\nkey2:${key21}\nvalue:${value1}`)
            setObj({...obj,
                
                    key1:key11,
                    key2:key21,
                    value:value1
                

        
            });
            // console.log(obj);


            setVal(val.concat(obj));
         
         }
       
 

}

when this data saved in val array it only print last calculated value.It does not provide all 16 object.I just did this in vanilla javascript.But i am facing problem in React js

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
salik saleem
  • 769
  • 5
  • 25

1 Answers1

1

This is because setting state value is async in React. So here your setVal is behaving asynchronously.

Problem: You are using the loop and inside it, you are doing setVal. But your loop does not wait for setVal to complete its operation(means your val is still empty [] and loop completes itself). Loop runs without waiting for setVal to complete. Hence until the last iteration, your val is [] and that's why it stores the last iteration value.

Try this:

 const dummyValArr = [];
 for(let i = 1; i<16; i++) {
    var key11=Math.exp(lmin+delta*(i-1)).toFixed(2);
    var key21=Math.exp(lmin+delta*((i+1)-1)).toFixed(2)
    let value1=colors[i];

    const dummyObj = {
        ...obj,
           key1:key11,
           key2:key21,
           value:value1                                
    }    
    setObj(dummyObj);
    dummyValArr.push(dummyObj); // just pushing, no async operation here. So it will store all the obj inside dummyValArr                   
}
setVal(dummyValArr); // setting it outside the loop
Surjeet Bhadauriya
  • 6,755
  • 3
  • 34
  • 52
  • 1
    Minor pedantic point, setting React state isn't `async`, the state updater functions are 100% synchronous functions that are neither declared `async` nor return a Promise, so they can't be waited for. React *asynchronously* processes these enqueued updates though. This is the reason why you must wait until the next render to access the new state values. – Drew Reese Sep 30 '21 at 06:24