getElementById после динамического добавления в React
Я динамически добавляю карты в свой функциональный компонент React. Карты хранятся в State. Я сопоставляю их и даю каждому из них идентификатор. OnClick на этих картах, я успешно получаю их идентификатор. Теперь я хочу getElementById, чтобы изменить цвет карты:
function Clicked(pressedGifId) {
if (pressedGifId === 'correctGif') CorrectMatch();
else WrongMatch();
}
function CorrectMatch(pressedGifId) {
// / THERE I GET Element: null
console.log('Element:', document.getElementById(pressedGifId));
}
function WrongMatch() {
console.log('wrong a match!');
}
export default function GameObject(props) {
const addedToGameGif = [];
const [pressedGifId, gifPressed] = useState(null);
const [photoCards, setPhotoCards] = useState([]);
useEffect(() => {
Clicked(pressedGifId);
}, [pressedGifId]);
// add randomly picked photos to addedToGameGif array
// ...
addedToGameGif.map(gifId =>
photoCards.push(
<Card id={gifId} onClick={() => gifPressed(gifId)}>
text
</Card>,
),
);
return <div>{photoCards}</div>;
}
Я пробовал изучать ссылки, но они предназначены только для компонентов класса. Итак, как мне добраться до своего элемента по идентификатору в React?
1 ответ
Вы можете использовать ref
в функциональной составляющей. Есть крючок под названиемuseRef
.
Примечание. Никогда не взаимодействуйте напрямую с
DOM
до тех пор, пока не появится доступный api для решения проблемы для этого конкретного варианта использования.В React не рекомендуется напрямую взаимодействовать с dom. Всегда используйте react apis для взаимодействия с dom. React разработан, чтобы скрыть DOM, потому что они хотят абстрагироваться от DOM. Используя DOM напрямую, вы нарушаете абстракцию и делаете свой код уязвимым для изменений, внесенных в библиотеку.
React поддерживает виртуальную
DOM
если мы внесем какие-либо изменения в актуальныеDOM
прямо тогдаreact
не будет знать об этом изменении, и это может привести к неожиданному поведению.
import React, {useState, useRef} from 'react';
export default function GameObject(props) {
const addedToGameGif = [];
const [pressedGifId, gifPressed] = useState(null);
const [photoCards, setPhotoCards] = useState([]);
const elemRef = useRef(null);
useEffect(() => {
Clicked(pressedGifId);
}, [pressedGifId]);
// add randomly picked photos to addedToGameGif array
// ...
addedToGameGif.map(gifId =>
photoCards.push(
<Card ref={elemRef} id={gifId} onClick={() => gifPressed(gifId)}>
text
</Card>
)
);
return <div>{photoCards}</div>;
}
Пример из официальных документов.
function TextInputWithFocusButton() {
const inputEl = useRef(null);
const onButtonClick = () => {
// `current` points to the mounted text input element
inputEl.current.focus();
};
return (
<>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</>
);
}