0

Since my pathfinding project has too many cells for me to animate it by changing state I was told to use ref. I went with the forward ref approach, which I assume works becase in devtools each cell appears with the forwardRef tag.

Even when I try to console.log each ref it points me to the correct cell in the grid. The problem is when I try to mutate a property like className/bgColor, program crashes and gives me a TypeError: Cannot add property className, object is not extensible.

const node = (props, ref) => {
    return (
        <div ref={ref}>
        </div >
    )
}
const Node = React.forwardRef(node);
export default Node
function Grid() {

    // How I created the refs
    const refCollection = useRef(matrix.map(rows => rows.map(nodes => React.createRef())));

    let grid = matrix.map((rows, i) => rows.map((_, j) => <Node
        ref={refCollection.current[i][j]}
    ></Node>))

    function createMazeAndAnimate() {
        const orderCarved = generateMaze(rows, cols, setWall, setStartNode,
            setGoalNode, setTraversed, setCarvedOrder);
        orderCarved.forEach(([y, x], i) => {
            setTimeout(() => {
                refCollection.current[y][x].className = 'traversed'; //PROGRAM CRASHES HERE
                console.log(refCollection.current[y][x]); // IF I JUST LOG THIS LINE I CAN 
                                                          // SEE EACH CELL REFERENCED 
                                                          // CORRECTLY
            }, i * 20);
        })
    }

    return (
        <>
            <Toolbar
                generateMaze={createMazeAndAnimate}
            />
            <div
                className='grid'
            >
                {grid.map((row, i) => <div key={i} className='board-row'>{row}</div>)}
            </div>
        </>
    )
}

Thank You!

1 Answers1

0

You're trying to modify refs directly. You don't mutate a ref object itself, you mutate whatever's in ref.current. So you want refCollection.current[y][x].current.

Putting a ref inside a ref is a code smell, as a ref itself is designed to be mutated, putting it inside something else you mutate seems extraneous. You might want to put your ref array in state instead.

Andy Ray
  • 30,372
  • 14
  • 101
  • 138