Почему я не могу напрямую управлять DOM с помощью React refs в моем проекте?

Поскольку в моем проекте поиска пути слишком много ячеек, чтобы я мог его анимировать, изменяя состояние, мне сказали использовать ref. Я использовал подход forward ref, который, как я полагаю, работает, потому что в devtools каждая ячейка отображается с тегом forwardRef.

Даже когда я пытаюсь создать console.log, каждая ссылка указывает мне на правильную ячейку в сетке. Проблема в том, что когда я пытаюсь изменить такое свойство, как className / bgColor, программа дает сбой и выдает ошибку TypeError: не удается добавить свойство className, объект не расширяется.

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>
        </>
    )
}

Спасибо!


person Alex M.    schedule 06.04.2021    source источник
comment
Вы пытаетесь напрямую изменить ссылки. Вы не изменяете сам объект ref, вы изменяете все, что находится в ref.current. Итак, вы хотите refCollection.current[y][x].current   -  person Andy Ray    schedule 07.04.2021
comment
чувак, спасибо тебе большое! ржу не могу   -  person Alex M.    schedule 07.04.2021


Ответы (1)


Вы пытаетесь напрямую изменить ссылки. Вы не изменяете сам объект ref, вы изменяете все, что находится в ref.current. Итак, вы хотите refCollection.current[y][x].current.

Помещение ссылки в ссылку - это запах кода, поскольку ссылка сама по себе предназначена для мутации, и размещение ее внутри чего-то еще, что вы изменяете, кажется посторонним. Возможно, вы захотите поместить свой ref массив в состоянии вместо.

person Andy Ray    schedule 06.04.2021