Search code examples
reactjsreact-hooksuse-stateuse-ref

React - UseState, UseRef..In Trouble


Can someone tell me whats wrong ?

I have a react function component where in I use 'useState' & 'UseRef' on a state variable like so..

    **A**. `const [nodeslist,_setNodeslist] = useState([]);`
    
    **B**. `const  nodeslistRef = useRef(nodeslist);`
    
    **C**.`const setNodeslist = (data)=>{
                nodeslistRef.current = data;
                _setNodeslist(data)
      }`
    
    **D**. somewhere ..on an event which adds nodes...

       `
       let n = {id:'someid',attrs:{name:'somename',descr:'somedescr'}};
       setNodeslist(prev=>[...prev,n]);
       `

    **E**. in another event handler...click.. I am trtying to find the node clicked..but I cant 
           iterate the 'nodeslist' with ref like so.. 

           `nodeslistRef.current.forEach((item,i)=>{
               .....
           });`

           ***GIVES ERROR nodeslistRef.current.forEach is NOT A FUNCTION..***

          a. `console.log(nodeslistRef.current)` shows -> prev=>[...prev,n] but not the DATA..
          b. `JSON.stringify(nodeslist)` on page shows expected data..and seems to updating as soon as 
             a node is added to the page..

SO WHATS WRONG ? Can someone help me ? just cant seem to get my head wrapped around it...

As an aside, I am using EXACTLY the same schematics with another state variable and it all works as expected...


Solution

  • You are wrong with this. setNodeslist(prev=>[...prev,n]); Since you did this. In here you will get data as function prev=>[...prev, n] not [...prev, n]

    const setNodeslist = (data)=>{
      nodeslistRef.current = data;
      _setNodeslist(data)
    }
    

    That's why you get error like following:

    prev=>[...prev,n] but not the DATA..
    

    To fix this: try this.

    const setNodeslist = (callback)=>{
      const newCallback = (prev) => {
        nodeslistRef.current = callback(prev);
        return nodesListRef.current;
      }
      _setNodeslist(newCallback)
    }