Last active
April 8, 2023 11:13
-
-
Save kettanaito/2ba1873c6fa0adf75e121eb2de92a7cb to your computer and use it in GitHub Desktop.
A draft for "withModal" HOC to allow easy modals in React.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export const SHOW_MODAL = 'SHOW_MODAL'; | |
export const showModal(modalId, modalParams) => ({ | |
type: SHOW_MODAL, | |
modalId, | |
modalParams | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* App.jsx */ | |
import React from 'react'; | |
import EmailChange from './EmailChange'; | |
import ConfirmationModal from './ConfirmationModal'; | |
export default class App extends React.Component { | |
render() { | |
return ( | |
<EmailChange /> | |
<ConfirmationModal /> | |
); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* ConfirmationModal.jsx */ | |
import React from 'react'; | |
import PropTypes from 'prop-types'; | |
import withModal from './withModal'; | |
class ConfirmationModal extends React.Component { | |
static propTypes = { | |
id: PropTypes.string.isReqiured | |
} | |
static defaultProps = { | |
id: 'confirmation' | |
} | |
handleConfirmClick = () => { | |
this.props.hideModal('confirmation'); // you may want to generate the action relevant to this id and pass it from HOC | |
} | |
render() { | |
const { modalParams } = this.props; | |
return ( | |
<div className="modal"> | |
<h1>Hey!</h1> | |
<p>Are you sure you want a "{ modalParams.email }" as your new email?</p> | |
<button onClick={ this.handleConfirmClick }>Confirm</button> | |
</div> | |
); | |
} | |
} | |
export default withModal(ConfirmationModal); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* EmailChange.jsx */ | |
import React from 'react'; | |
import { connect } from 'react-redux'; | |
class EmailChange extends React.Component { | |
render() { | |
return ( | |
<div> | |
<button onClick={() => { | |
this.props.showModal('confirmation', { email: 'foo@reactjs.com' }); | |
}}> | |
Change email | |
</button> | |
</div> | |
); | |
} | |
} | |
export default connect(undefined, { showModal })(EmailChange); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as actions from './actions'; | |
const initialState = { | |
ids: [], | |
params: {} | |
}; | |
export default function modalReducer(state, action) { | |
switch (action.type) { | |
case actions.SHOW_MODAL: | |
const { modalId, modalParams } = action; | |
const nextState = Object.assign({}, state, { modalParams }); | |
if (state.modals.includes(modalId)) { | |
nextState.ids.splice(state.ids.indexOf(modalId), 1); | |
} else { | |
nextState.ids = state.ids.concat(modalId); | |
} | |
return nextState; | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* withModal.jsx */ | |
import React from 'react'; | |
import { connect } from 'react-redux'; | |
import { showModal, hideModal } from './actions'; | |
export default function withModal(CustomModal) { | |
class ModalWrapper extends React.Component { | |
render() { | |
const { id, modals } = this.props; | |
if (!modals.ids.ncludes(id)) return null; | |
return React.createElement(CustomModal, this.props); | |
} | |
} | |
return connect(state => ({ | |
modals: state.modals, | |
modalParams: state.modals.params | |
}), { showModal, hideModal })(ModalWrapper); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment