Skip to content

Instantly share code, notes, and snippets.

@nikonov91-dev
Last active January 23, 2019 08:20
Show Gist options
  • Save nikonov91-dev/aec2dab9e5d191abf0ce0ba3c5d0dd45 to your computer and use it in GitHub Desktop.
Save nikonov91-dev/aec2dab9e5d191abf0ce0ba3c5d0dd45 to your computer and use it in GitHub Desktop.
replace jquery component with react component in vanilla js
//the source https://medium.com/@andreasmcd/how-my-team-converted-our-website-from-jquery-to-react-in-small-steps-cd4390f0a146
//before :
// The controller manages all events and will update the page as necessary.
// In this example there is not much happening.
// But in our real application, these controllers could be very large and own a lot of logic.
class Controller {
constructor() {
this.$openModalBtn = $('#openModal');
this.$mediaModal = $('#mediaModal');
this.setupEvents();
}
setupEvents() {
this.$openModalBtn.click(() => {
// Set dynamic content. This might come from an api in a real application and be rendered with handlebars instead.
this.$mediaModal
.find('.modal-body')
.html('<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed congue id arcu in cursus. In est justo, rutrum a ultrices quis, dapibus vel odio. Aliquam a diam elit.</p>');
// Show modal
this.$mediaModal.modal('show');
});
}
}
const controller = new Controller();
//after
function MediaModal({children, onClose}) {
return (
<div
id="mediaModal"
className="modal show"
style={{display: 'block'}}
>
<div className="modal-dialog" role="document">
<div className="modal-content">
<div className="modal-header">
<h5 className="modal-title">Modal title</h5>
<button
type="button"
className="close"
aria-label="Close"
onClick={onClose}
>
<span aria-hidden="true">&times;</span>
</button>
</div>
<div className="modal-body">{children}</div>
<div className="modal-footer">
<button
className="btn btn-secondary"
onClick={onClose}
>Close</button>
</div>
</div>
</div>
</div>
);
}
// This wrapper class handles the state changes and interaction with non-React code. This would later be removed.
class MediaModalWrapper {
constructor({element, content, startOpen} = {}) {
this.element = element;
// Optional starting props
this.content = content;
this.isOpen = startOpen;
// In a real application we might also want other props like a onClose callback to notify the rest of the application when the modal closes.
// Render
this.render();
}
// Called by application to open modal.
open(content) {
// Update state and rerender open
this.isOpen = true;
this.content = content;
this.render();
}
handleClose = () => {
// Update state and rerender closed
this.isOpen = false;
this.render();
};
render() {
// Our wrappers for dialogs generally include a div that is always rendered, even when the dialog is closed.
// The alternative would be to render the modal on open and then remove it from the DOM on closed using React.unmountComponentAtNode. We found that this method generally caused us less grief.
ReactDOM.render(
<div>
{this.isOpen &&
<MediaModal onClose={this.handleClose}>
<p>
{this.content}
</p>
</MediaModal>}
</div>,
this.element
);
}
}
// This has barely changed. Instead of a jQuery object for the modal, we now have an instane of our new class.
class Controller {
constructor() {
this.$openModalBtn = $('#openModal');
// Create an instance of our wrapper class and tell it where to render to. If we cared when the modal closed we could also add a callback here for that.
this.mediaModal = new MediaModalWrapper({
element: document.getElementById('modalContainer')
});
this.setupEvents();
}
setupEvents() {
$('#openModal').click(() => {
// Call open with the content.
this.mediaModal.open('Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed congue id arcu in cursus. In est justo, rutrum a ultrices quis, dapibus vel odio. Aliquam a diam elit.');
});
}
}
const controller = new Controller();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment