Search code examples
reactjsuse-state

React State Rendering one step behind


I have a function that handles dragging an element on a page and swapping that element with the target element (using onDragStart & onDrop). The function takes in exactly where the user is at on a page and updates the page layout accordingly (not super important for my question). Everything works except the rendering is one action behind. Even weirder, if left alone it eventually updates after 10 or so seconds, but is instant after trying the action again. I believe the useState 'set' is being called before the array has a chance to update. Any tips?

// This function is called when the element is grabbed
      const handleElementDrag = (index) => {
        setDragElementID(index)
      }

      // This function is called when the element is dropped
      const handleElementDrop = async (index, page, container, section) => {
        // Sanity Check
        console.log('dropped', dragElementID, 'onto', index, 'page:', page, 'container:', container, 'section:', section, ' - element level')

        // Declare new array based on current page structure
        const newElementOrder = PDFStructure;

        // Swap array elements
        [newElementOrder[page].contents[container].contents[section].contents[dragElementID], newElementOrder[page].contents[container].contents[section].contents[index]] = [newElementOrder[page].contents[container].contents[section].contents[index], newElementOrder[page].contents[container].contents[section].contents[dragElementID]]
        
        // Update current layout
        setPDFStructure(newElementOrder)
      }

Solution

  • Figured it out, I needed to use the spread operator in the setHook call

            setPDFStructure([...newElementOrder])
    

    The reason for this is because react will not re-render if only part of an array is changed