[英]React TypeScript document.getElementById always selects the first instance
我已經渲染了兩個相同的組件
<div><Modal title='Join'/></div>
<div><Modal title='Login'/></div>
模態分量是這樣的
import React, {useState} from 'react';
import {Join} from './join';
import {Login} from './login';
interface propsInterface {
title: string;
}
const Modal: React.FC<propsInterface> = (props) => {
const [state, setState] = useState({showLogin: props.title === "login" ? false : true});
let modalState = false;
function toggleLogin(event: any) {
setState({...state, showLogin: !state.showLogin});
}
function toggleModal(event: any) {
if (event.target.id !== 'modal') return;
modalState = !modalState;
const modal = document.getElementById('modal'); <<==this always selects the first one
const card = document.getElementById('card'); <<==this always selects the first one
if (modal && card && modalState === true) {
modal.style.display = "flex";
modal.animate([{backgroundColor: 'rgba(0, 0, 0, 0)'}, {backgroundColor: 'rgba(0, 0, 0, 0.6)'}], {duration: 200, easing: 'ease-in-out', fill: 'forwards'});
card.animate([{opacity: 0}, {opacity: 1}], {duration: 200, easing: 'ease-in-out', fill: 'forwards'});
card.animate([{transform: 'translateY(-200px)'}, {transform: 'translateY(0)'}], {duration: 200, easing: 'ease-in-out', fill: 'forwards'});
}
if (modal && card && modalState === false) {
modal.animate([{backgroundColor: 'rgba(0, 0, 0, 0.6)'}, {backgroundColor: 'rgba(0, 0, 0, 0)'}], {duration: 200, easing: 'ease-in-out', fill: 'forwards'});
card.animate([{opacity: 1}, {opacity: 0}],{duration: 200, easing: 'ease-in-out', fill: 'forwards'});
card.animate([{transform: 'translateY(0)'}, {transform: 'translateY(-200px)'}], {duration: 200, easing: 'ease-in-out', fill: 'forwards'});
setTimeout(() => modal.style.display = "none", 200);
}
}
return (
<div>
<div className='modal' id='modal' onClick={toggleModal}>
<div className='card' id='card'>
{props.title}
{state.showLogin
? <Login toggleLogin={toggleLogin} toggleModal={toggleModal}/>
: <Join toggleLogin={toggleLogin} toggleModal={toggleModal}/>}
</div>
</div>
<div onClick={toggleModal} className='modal-title' id='modal'> {props.title}</div>
</div>
);
}
export {Modal};
因為當我使用時,dom中現在有2個組件
const modal = document.getElementById('modal');
組件的第一個實例按預期工作,但是第二個實例選擇第一個實例,而不選擇第二個實例。
有一種方法只能在此組件中獲取getElementById嗎?
同一頁上只能有一個具有給定id的元素,在這種情況下,您可能要使用類並使用document.getElementsByClassName("classname")
,這將返回具有給定類名的元素數組。
希望這可以幫助
可以將字段的ID作為props傳遞,然后設置其id屬性,而不是將ID設置為``模態'',然后對它們使用getElementById。
您可以這樣做:
<Modal title='Join' UniqId="modal1"/>
<Modal title='Login' UniqId="modal2"/>
然后,在組件中,您可以執行以下操作:
<div className='modal' id={props.UniqId} onClick={toggleModal}>
之后,在您的JS文件中,您可以使用以下ID:
const modal1 = document.getElementById('modal1');
const modal2 = document.getElementById('modal2');
這樣做的方式似乎仍然是在使用事件發生后使用原始JavaScript來操縱DOM元素的心態。
通常,在React世界中,您應該將所有內容都鏈接到render()
方法中,該方法在每當react組件中的狀態或屬性發生更改時都會引發。
因此,在您遇到的情況下,我將刪除所有獲取DOM元素的代碼(例如您的document.getElementById
代碼),然后純粹從狀態更改中進行工作。 很抱歉,這不是完整的代碼,因為我不確定您的UI應該是什么樣。
const Modal: React.FC<propsInterface> = (props) => {
const [state, setState] = useState({ showLogin: props.title === "login" ? false : true, showModal: false, showCard: false });
function toggleLogin() {
setState({ showLogin: !state.showLogin });
}
function toggleModal() {
setState({ showModal: !state.showModal, showCard: !state.showCard });
}
const modalClassName = state.showModal ? 'modal show' : 'modal';
const cardClassName = state.showLogin ? 'card show' : 'card';
return (
<div>
<div className={modalClassName} onClick={toggleModal}>
<div className={cardClassName}>
{props.title}
{state.showLogin
? <Login toggleLogin={toggleLogin} toggleModal={toggleModal}/>
: <Join toggleLogin={toggleLogin} toggleModal={toggleModal}/>}
</div>
</div>
<div onClick={toggleModal} className='modal-title' id='modal'> {props.title}</div>
</div>
);
}
實際上發生的是,當調用toggleModal
方法時,它僅在true / false之間切換兩個狀態屬性。 這將導致組件重新呈現,並且類名稱在div
元素上更改。
由此,您將需要將所有動畫移到CSS文件中,並可能在其中使用動畫(css動畫不是我的最大技能)。 這不是對您擁有的東西的簡單更改,但是我將始終將樣式和動畫保留在組件外部和css文件中,並且始終從渲染工作,而不是嘗試在渲染后操作React節點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.