Reactjs 为什么React.createPortal不';t处理事件。停止播放?
我正在使用React.createPortal对自定义模式进行试验,如果我只是通过模式内的按钮打开和关闭模式,并且默认结果显示在下面的组件上,那么一切都正常,但我想要实现的是,当我单击模式容器(暗覆盖div)时,它应该关闭模式,因此,我在它上面添加了一个exithandler,但问题是,即使exithandler中有event.stopperPagation()函数,模式内容中的默认表单按钮行为也不再起作用 下面是两个模态的codesandbox示例,一个有表单,一个没有表单: 模态容器:Reactjs 为什么React.createPortal不';t处理事件。停止播放?,reactjs,Reactjs,我正在使用React.createPortal对自定义模式进行试验,如果我只是通过模式内的按钮打开和关闭模式,并且默认结果显示在下面的组件上,那么一切都正常,但我想要实现的是,当我单击模式容器(暗覆盖div)时,它应该关闭模式,因此,我在它上面添加了一个exithandler,但问题是,即使exithandler中有event.stopperPagation()函数,模式内容中的默认表单按钮行为也不再起作用 下面是两个模态的codesandbox示例,一个有表单,一个没有表单: 模态容器: im
import React from "react";
import { createPortal } from "react-dom";
const modalRoot = document.getElementById("modal-root");
function Modal({ exitHandler, children }) {
return createPortal(
<div className="modal" onClick={exitHandler}>
{children}
</div>,
modalRoot
);
}
export default Modal;
import React from "react";
const HelloWorld = ({ user, onClose }) => {
return (
<div className="modal-content">
<div className="modal-header">
<div className="modal-title">
<h2>Greetings</h2>
</div>
<div className="modal-action">
<button type="button" onClick={onClose}>X</button>
</div>
</div>
<div className="modal-body">
<p>{user ? `Hello ${user}!` : "Greetings!"}</p>
</div>
</div>
);
};
export default HelloWorld;
import React, { forwardRef, useEffect } from "react";
const SignUp = forwardRef((props, ref) => {
const { onClose, onSignUp, handleChange, inputError, user } = props;
useEffect(() => {
ref.current.focus();
});
return (
<div className="modal-content">
<div className="modal-header">
<div className="modal-title">
<h2>Sign Up</h2>
</div>
<div className="modal-action">
<button type="button" onClick={onClose}>X</button>
</div>
</div>
<div className="modal-body">
<form onSubmit={onSignUp} className="modal-form">
<label className="input-label">
<span>Name:</span>
<input
type="text"
onChange={handleChange}
value={user}
ref={ref}
className={inputError === true ? "input-error" : null}
/>
</label>
<input className="btn" type="submit" value="Submit" />
</form>
</div>
</div>
);
});
export default SignUp;
const App = () => {
const [modalState, setModalState] = useState(false);
const [modalId, setModalId] = useState(null);
const [inputError, setInputError] = useState(false);
const [user, setUser] = useState("");
const [userStatus, setUserStatus] = useState("");
const nameRef = useRef(null);
const handleShowModal = (e) => {
const modalId = e.target.id.toString();
return [setModalState(true), setModalId(modalId)];
};
const handleHideModal = (event) => {
event.stopPropagation(); // This doesn't work
setModalState(false);
};
const runSignUpResult = useCallback(() => {
handleHideModal();
setUserStatus(`Thank you ${user} for signing up!`);
}, [user]);
const handleValidation = useCallback(
(nameParameter) => {
if (nameParameter.length === 0) {
nameRef.current.focus();
setInputError(true);
} else {
return [setInputError(false), runSignUpResult()];
}
},
[runSignUpResult]
);
const handleSignUp = useCallback(
(e) => {
e.preventDefault();
const name = nameRef.current.value;
handleValidation(name);
},
[nameRef, handleValidation]
);
const handleChange = (e) => {
setUser(e.target.value);
};
const modal = modalState ? (
<Modal exitHandler={handleHideModal}>
{modalId === "greeting" ? (
<HelloWorld onClose={handleHideModal} user={user} />
) : (
<SignUp
onClose={handleHideModal}
onSignUp={handleSignUp}
handleChange={handleChange}
user={user}
ref={nameRef}
inputError={inputError}
modalId={modalId}
/>
)}
</Modal>
) : null;
return (
<div className="App">
<AppHeader />
<main className="app-body">
<section className="modal-btns">
<button id="greeting" className="btn" onClick={handleShowModal}>
Greetings!
</button>
<button id="signup" className="btn" onClick={handleShowModal}>
Sign Up
</button>
</section>
<section>{modal}</section>
<section className="user-status">
<h3>{user.length === 0 ? null : userStatus}</h3>
</section>
</main>
</div>
);
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
从“React”导入React;
从“react dom”导入{createPortal};
const modalRoot=document.getElementById(“模态根”);
函数模态({exitHandler,children}){
返回createPortal(
{儿童}
,
莫代尔根
);
}
导出默认模式;
模态内容1:
import React from "react";
import { createPortal } from "react-dom";
const modalRoot = document.getElementById("modal-root");
function Modal({ exitHandler, children }) {
return createPortal(
<div className="modal" onClick={exitHandler}>
{children}
</div>,
modalRoot
);
}
export default Modal;
import React from "react";
const HelloWorld = ({ user, onClose }) => {
return (
<div className="modal-content">
<div className="modal-header">
<div className="modal-title">
<h2>Greetings</h2>
</div>
<div className="modal-action">
<button type="button" onClick={onClose}>X</button>
</div>
</div>
<div className="modal-body">
<p>{user ? `Hello ${user}!` : "Greetings!"}</p>
</div>
</div>
);
};
export default HelloWorld;
import React, { forwardRef, useEffect } from "react";
const SignUp = forwardRef((props, ref) => {
const { onClose, onSignUp, handleChange, inputError, user } = props;
useEffect(() => {
ref.current.focus();
});
return (
<div className="modal-content">
<div className="modal-header">
<div className="modal-title">
<h2>Sign Up</h2>
</div>
<div className="modal-action">
<button type="button" onClick={onClose}>X</button>
</div>
</div>
<div className="modal-body">
<form onSubmit={onSignUp} className="modal-form">
<label className="input-label">
<span>Name:</span>
<input
type="text"
onChange={handleChange}
value={user}
ref={ref}
className={inputError === true ? "input-error" : null}
/>
</label>
<input className="btn" type="submit" value="Submit" />
</form>
</div>
</div>
);
});
export default SignUp;
const App = () => {
const [modalState, setModalState] = useState(false);
const [modalId, setModalId] = useState(null);
const [inputError, setInputError] = useState(false);
const [user, setUser] = useState("");
const [userStatus, setUserStatus] = useState("");
const nameRef = useRef(null);
const handleShowModal = (e) => {
const modalId = e.target.id.toString();
return [setModalState(true), setModalId(modalId)];
};
const handleHideModal = (event) => {
event.stopPropagation(); // This doesn't work
setModalState(false);
};
const runSignUpResult = useCallback(() => {
handleHideModal();
setUserStatus(`Thank you ${user} for signing up!`);
}, [user]);
const handleValidation = useCallback(
(nameParameter) => {
if (nameParameter.length === 0) {
nameRef.current.focus();
setInputError(true);
} else {
return [setInputError(false), runSignUpResult()];
}
},
[runSignUpResult]
);
const handleSignUp = useCallback(
(e) => {
e.preventDefault();
const name = nameRef.current.value;
handleValidation(name);
},
[nameRef, handleValidation]
);
const handleChange = (e) => {
setUser(e.target.value);
};
const modal = modalState ? (
<Modal exitHandler={handleHideModal}>
{modalId === "greeting" ? (
<HelloWorld onClose={handleHideModal} user={user} />
) : (
<SignUp
onClose={handleHideModal}
onSignUp={handleSignUp}
handleChange={handleChange}
user={user}
ref={nameRef}
inputError={inputError}
modalId={modalId}
/>
)}
</Modal>
) : null;
return (
<div className="App">
<AppHeader />
<main className="app-body">
<section className="modal-btns">
<button id="greeting" className="btn" onClick={handleShowModal}>
Greetings!
</button>
<button id="signup" className="btn" onClick={handleShowModal}>
Sign Up
</button>
</section>
<section>{modal}</section>
<section className="user-status">
<h3>{user.length === 0 ? null : userStatus}</h3>
</section>
</main>
</div>
);
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
从“React”导入React;
常量HelloWorld=({user,onClose})=>{
返回(
问候语
X
{user?`Hello${user}!`:“问候!”}
);
};
导出默认HelloWorld;
模态内容2:
import React from "react";
import { createPortal } from "react-dom";
const modalRoot = document.getElementById("modal-root");
function Modal({ exitHandler, children }) {
return createPortal(
<div className="modal" onClick={exitHandler}>
{children}
</div>,
modalRoot
);
}
export default Modal;
import React from "react";
const HelloWorld = ({ user, onClose }) => {
return (
<div className="modal-content">
<div className="modal-header">
<div className="modal-title">
<h2>Greetings</h2>
</div>
<div className="modal-action">
<button type="button" onClick={onClose}>X</button>
</div>
</div>
<div className="modal-body">
<p>{user ? `Hello ${user}!` : "Greetings!"}</p>
</div>
</div>
);
};
export default HelloWorld;
import React, { forwardRef, useEffect } from "react";
const SignUp = forwardRef((props, ref) => {
const { onClose, onSignUp, handleChange, inputError, user } = props;
useEffect(() => {
ref.current.focus();
});
return (
<div className="modal-content">
<div className="modal-header">
<div className="modal-title">
<h2>Sign Up</h2>
</div>
<div className="modal-action">
<button type="button" onClick={onClose}>X</button>
</div>
</div>
<div className="modal-body">
<form onSubmit={onSignUp} className="modal-form">
<label className="input-label">
<span>Name:</span>
<input
type="text"
onChange={handleChange}
value={user}
ref={ref}
className={inputError === true ? "input-error" : null}
/>
</label>
<input className="btn" type="submit" value="Submit" />
</form>
</div>
</div>
);
});
export default SignUp;
const App = () => {
const [modalState, setModalState] = useState(false);
const [modalId, setModalId] = useState(null);
const [inputError, setInputError] = useState(false);
const [user, setUser] = useState("");
const [userStatus, setUserStatus] = useState("");
const nameRef = useRef(null);
const handleShowModal = (e) => {
const modalId = e.target.id.toString();
return [setModalState(true), setModalId(modalId)];
};
const handleHideModal = (event) => {
event.stopPropagation(); // This doesn't work
setModalState(false);
};
const runSignUpResult = useCallback(() => {
handleHideModal();
setUserStatus(`Thank you ${user} for signing up!`);
}, [user]);
const handleValidation = useCallback(
(nameParameter) => {
if (nameParameter.length === 0) {
nameRef.current.focus();
setInputError(true);
} else {
return [setInputError(false), runSignUpResult()];
}
},
[runSignUpResult]
);
const handleSignUp = useCallback(
(e) => {
e.preventDefault();
const name = nameRef.current.value;
handleValidation(name);
},
[nameRef, handleValidation]
);
const handleChange = (e) => {
setUser(e.target.value);
};
const modal = modalState ? (
<Modal exitHandler={handleHideModal}>
{modalId === "greeting" ? (
<HelloWorld onClose={handleHideModal} user={user} />
) : (
<SignUp
onClose={handleHideModal}
onSignUp={handleSignUp}
handleChange={handleChange}
user={user}
ref={nameRef}
inputError={inputError}
modalId={modalId}
/>
)}
</Modal>
) : null;
return (
<div className="App">
<AppHeader />
<main className="app-body">
<section className="modal-btns">
<button id="greeting" className="btn" onClick={handleShowModal}>
Greetings!
</button>
<button id="signup" className="btn" onClick={handleShowModal}>
Sign Up
</button>
</section>
<section>{modal}</section>
<section className="user-status">
<h3>{user.length === 0 ? null : userStatus}</h3>
</section>
</main>
</div>
);
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
import React,{forwardRef,useffect}来自“React”;
const SignUp=forwardRef((道具,ref)=>{
const{onClose,onSignUp,handleChange,inputeror,user}=props;
useffect(()=>{
ref.current.focus();
});
返回(
注册
X
姓名:
);
});
导出默认注册;
Main:
import React from "react";
import { createPortal } from "react-dom";
const modalRoot = document.getElementById("modal-root");
function Modal({ exitHandler, children }) {
return createPortal(
<div className="modal" onClick={exitHandler}>
{children}
</div>,
modalRoot
);
}
export default Modal;
import React from "react";
const HelloWorld = ({ user, onClose }) => {
return (
<div className="modal-content">
<div className="modal-header">
<div className="modal-title">
<h2>Greetings</h2>
</div>
<div className="modal-action">
<button type="button" onClick={onClose}>X</button>
</div>
</div>
<div className="modal-body">
<p>{user ? `Hello ${user}!` : "Greetings!"}</p>
</div>
</div>
);
};
export default HelloWorld;
import React, { forwardRef, useEffect } from "react";
const SignUp = forwardRef((props, ref) => {
const { onClose, onSignUp, handleChange, inputError, user } = props;
useEffect(() => {
ref.current.focus();
});
return (
<div className="modal-content">
<div className="modal-header">
<div className="modal-title">
<h2>Sign Up</h2>
</div>
<div className="modal-action">
<button type="button" onClick={onClose}>X</button>
</div>
</div>
<div className="modal-body">
<form onSubmit={onSignUp} className="modal-form">
<label className="input-label">
<span>Name:</span>
<input
type="text"
onChange={handleChange}
value={user}
ref={ref}
className={inputError === true ? "input-error" : null}
/>
</label>
<input className="btn" type="submit" value="Submit" />
</form>
</div>
</div>
);
});
export default SignUp;
const App = () => {
const [modalState, setModalState] = useState(false);
const [modalId, setModalId] = useState(null);
const [inputError, setInputError] = useState(false);
const [user, setUser] = useState("");
const [userStatus, setUserStatus] = useState("");
const nameRef = useRef(null);
const handleShowModal = (e) => {
const modalId = e.target.id.toString();
return [setModalState(true), setModalId(modalId)];
};
const handleHideModal = (event) => {
event.stopPropagation(); // This doesn't work
setModalState(false);
};
const runSignUpResult = useCallback(() => {
handleHideModal();
setUserStatus(`Thank you ${user} for signing up!`);
}, [user]);
const handleValidation = useCallback(
(nameParameter) => {
if (nameParameter.length === 0) {
nameRef.current.focus();
setInputError(true);
} else {
return [setInputError(false), runSignUpResult()];
}
},
[runSignUpResult]
);
const handleSignUp = useCallback(
(e) => {
e.preventDefault();
const name = nameRef.current.value;
handleValidation(name);
},
[nameRef, handleValidation]
);
const handleChange = (e) => {
setUser(e.target.value);
};
const modal = modalState ? (
<Modal exitHandler={handleHideModal}>
{modalId === "greeting" ? (
<HelloWorld onClose={handleHideModal} user={user} />
) : (
<SignUp
onClose={handleHideModal}
onSignUp={handleSignUp}
handleChange={handleChange}
user={user}
ref={nameRef}
inputError={inputError}
modalId={modalId}
/>
)}
</Modal>
) : null;
return (
<div className="App">
<AppHeader />
<main className="app-body">
<section className="modal-btns">
<button id="greeting" className="btn" onClick={handleShowModal}>
Greetings!
</button>
<button id="signup" className="btn" onClick={handleShowModal}>
Sign Up
</button>
</section>
<section>{modal}</section>
<section className="user-status">
<h3>{user.length === 0 ? null : userStatus}</h3>
</section>
</main>
</div>
);
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
const-App=()=>{
const[modalState,setModalState]=useState(false);
const[modalId,setModalId]=useState(null);
const[inputError,setInputError]=useState(false);
const[user,setUser]=useState(“”);
const[userStatus,setUserStatus]=useState(“”);
const nameRef=useRef(null);
常量handleshowmodel=(e)=>{
const modalId=e.target.id.toString();
返回[setModalState(true),setModalId(modalId)];
};
const handleHideModal=(事件)=>{
event.stopPropagation();//这不起作用
setModalState(假);
};
const runSignUpResult=useCallback(()=>{
handleHideModal();
setUserStatus(`Thank you${user}感谢您的注册!`);
},[用户];
const handleValidation=useCallback(
(名称参数)=>{
如果(nameParameter.length==0){
nameRef.current.focus();
设置输入程序(真);
}否则{
返回[setInputError(false),runSignUpResult()];
}
},
[运行注册结果]
);
const handleSignUp=useCallback(
(e) =>{
e、 预防默认值();
const name=nameRef.current.value;
手推车(名称);
},
[名称参考,扶手电梯]
);
常数handleChange=(e)=>{
设置用户(如目标值);
};
常量模态=模态状态(
{modalId===“问候语”(
) : (
)}
):null;
返回(
问候语!
注册
{modal}
{user.length==0?null:userStatus}
);
};
const rootElement=document.getElementById(“根”);
render(,rootElement);
我认为问题在于react不理解父子关系,因为组件是在渲染后从外部添加的。合成事件处理由react本身完成。在处理内容可编辑div时,我遇到了类似的问题。我提出的解决方案是为这个孩子创建一个ref并使用addEventhandler。这是一项肮脏的工作,但似乎起了作用。也许对你有用。嗨@Sujit.Warrier你是说摩代尔的孩子?模态内容?模态就是我相信的那个孩子