我正在构建一个显示多个模态的页面。我想重用相同的模态但是当单击一个按钮时,应用程序会将不同的内容加载到模态中。
WIP CodePen:
https://codepen.io/jtsharpsite/pen/gorvjR
render() {
return ReactDOM.createPortal(
this.props.children,
domNode,
);
}
我非常接近我认为可行的方式,但我无法弄清楚如何将另一个组件附加到已经附加的模态组件。
我有一个按钮,它调用打开模态的处理程序并指定组件类型。
<button onClick={this.handleShow.bind(this, "p3009", "product")}>
Product 3009
</button>
<button onClick={this.handleShow.bind(this, "s1", "special")}>
Special #1
</button>
处理程序位于App上下文中并打开模态兄弟:
handleShow(modalId, modalType) {
this.setState({ showModal: true });
}
当模态组件安装完毕后,我会尝试在安装时附加产品。
componentDidMount() {
//TODO how to append to parent modal?
modalRoot.appendChild(this.el);
}
如何将 <Product>
或 <Special>
移至 <Modal>
?
答案 0 :(得分:0)
您是否尝试在门户网站中使用父子模式。
例如,让你的孩子像这样,让ModalDisplay呈现它的孩子。我不知道你想要做什么是可能的,因为我认为它需要门户网站来支持片段,我不确定它们是否会这样做。
我不知道我的问题背景是否正确但是你的想法是一样的,你有一个孩子本身有孩子,而不是在门户网站电话中有超过1个孩子。
<ModalDisplay>
<Special title="special" text="text" />
<Product title="product" pic="picture" />
</ModalDisplay>
答案 1 :(得分:0)
这是一个可重复使用的模态形式的例子......这里有很多你不需要的东西,但只需要注意handleSubmit。在handleSubmit中我们调用onComplete(),它可以是我们调用它时传递给可重用模式的任何函数,基于我们希望我们的模态执行的函数...在我们的例子中它是捕获用户名,密码等。
class ReusableModalForm extends React.Component {
constructor(props){
super(props);
this.state ={
};
}
handleChange(e) {
let {name, value} = e.target;
this.setState({
[name]: value,
usernameError: name === 'username' && !value ? 'username must have a value' : null,
emailError: name === 'email' && !value ? 'email must have a value' : null,
passwordError: name === 'password' && !value ? 'password must have a value' : null,
});
}
handleSubmit(e) {
e.preventDefault();
this.props.onComplete(this.state)
}
render() {
return (
<Modal
open={this.state.createAccountModalOpen}
trigger={<Link size="m" theme="bare" href="#" className="main-menu-item" onClick={this.handleSubmit}>{this.props.buttonText}</Link>}
closeIcon
onClose={() => { this.setState({
createAccountModalOpen: false,
}); }}
>
<Header icon='add user' content='Create account' />
<Modal.Content>
<Form />
</Modal.Content>
<Modal.Actions>
<Button color='green' onClick={this.handleSubmit}>
<Icon name='add user' /> {this.props.buttonText}
</Button>
</Modal.Actions>
</Modal>
);
}
}
export default ReusableModalForm;
基于这个逻辑,你可以构造一个带有一系列“触发器文本”的模态,只根据你使用可重用模态时传递的道具类型来渲染某些东西。
实施例。
<ReusableModal triggerText={'showAdress'} onComplete={this.showUsersHomeOnGoogle} />
然后在你的reusableModal某处......
{this.props.triggerText === showAdress ? this.setState=({showHomeAdressPortion: true)}
更新
class App extends React.Component {
constructor(props) {
super(props);
this.state = { showModal: false };
this.handleShow = this.handleShow.bind(this);
this.handleHide = this.handleHide.bind(this);
}
handleShow(modalId, modalType) {
console.log(
"Append content with ID: " + modalId + " of component type: " + modalType
);
//Here you should do a "fetch" first and grab your entire product information based on chosen ID and store it to state as an object...
//setState({activePortal: someContentObject})
//Then... I would use promise or aync await, show modal...
//Have Modal display from this state object
this.setState({ showModal: true, activePortal: });
//if it is a product
if (modalType == "product") {
//fetch additional images and add to state
//add images to {product.additionalPics}
}
//TODO re-render the modal with the appending element portal
}
handleHide() {
this.setState({ showModal: false });
}
render() {
//console.log("RENDER App");
// Show a Modal on click.
const modal = this.state.showModal ? (
<Modal>
<div className="modal">
<div className="modal-content-wrapper">
{/* I think what you're asking to do here is display basically "any" information that comes from a product fetch. This isnt possible without templeting somehow.. You will have to hard code like "title" "body" "image" into this modal...
<h1>this.state.activeProduct.title</h1>*/}
{/* CONTENT NEEDS TO GO HERE SOMEHOW */}
{this.props.children}
</div>
<button onClick={this.handleHide}>Hide modal</button>
</div>
</Modal>
) : null;