0

I am new to React and am trying to get up to speed on a few basic concepts, trying to shoehorn it into an existing application (with the intention of slowly converting the entire app into React). So this may be a vary basic question.

I am converting my dialogs first (my app has a bunch of bootstrap modal dialogs), so I am using react-modal library to create these dialogs. What I would like to do is make the outer markup for this dialog reusable across all my dialogs. For instance, with this render method:

render() {
        return(
            <Modal
                className="Modal__Bootstrap modal-dialog"
                closeTimeoutMS={150}
                isOpen={this.state.modalIsOpen}
                onRequestClose={this.handleModalCloseRequest}
            >
                <div className="modal-content">
                    <div className="modal-header">
                        <button type="button" className="close" onClick={this.handleModalCloseRequest}>
                            <span aria-hidden="true">&times;</span>
                            <span className="sr-only">Close</span>
                        </button>
*******INSERT HEADER COMPONENT*******
                    </div>
                    <div className="modal-body">
*******INSERT BODY COMPONENT*******    
                    </div>
                    <div className="modal-footer">
                        <button type="button" className="btn btn-default" onClick={this.handleModalCloseRequest}>Cancel</button>

*******INSERT ADDITIONAL FOOTER BUTTONS COMPONENT*******

                    </div>
                </div>
            </Modal>
        );
    }

I would like to have the lines that start with the ******** to be variable components that are appropriate (and different) for each dialog.

Obviously, for each dialog, I could just copy and paste this render method into that dialog's class and have hard coded components for that dialog. Something like (for the body):

                    <div className="modal-body">
                        <DialogABody />
                    </div>

and:

                    <div className="modal-body">
                        <DialogBBody />
                    </div>

But if I do that, I am then duplicating all the markup for the dialog "chrome" in react.

Essentially, I need some sort of dynamic component?

Is this possible?

0

3 Answers 3

1

on your modal react class you want to do this

class Modal extends React.Component {
    render() {
        return (
            <div>
            {this.props.header ? <HeaderComponent text={this.props.header} /> : null }
            {this.props.children}
            {this.props.footer ? <FooterComponent text={this.props.footer} /> : null }
            </div>
    }
}

then when calling this pass your props

<Modal
    className="Modal__Bootstrap modal-dialog"
    closeTimeoutMS={150}
    isOpen={this.state.modalIsOpen}
    onRequestClose={this.handleModalCloseRequest}
    header="My Header"
    footer="My Footer"
>

as for the body component part you should pass that as a prop to this dialog class when calling it.

instead of this:

<div className="modal-body">
    <DialogABody />
</div>

you should have this:

<div className="modal-body">
    {this.props.dialogComponent}
</div>

which gets passed through on the parent to this class

Sign up to request clarification or add additional context in comments.

1 Comment

That's awesome. On the footer, though, I want to pass in additional buttons (most dialogs are just save and cancel, but some have additional functions) not just text. Can I just pass a component in to "footer"?
1

Call your model dialog with the wanted components as props.

<model header={headerComponent} body={bodyComponent}/>

In model render just put {this.props.header} and so on.

Comments

1

for one child component you could simply use this.props.children, however, as you have 3 components, you need to put them into separate props:

<DialogBody header={<div>header</div>} body={<div>body</div>} footer={<div>footer</div>}/>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.