I have a screen and I need to show multiple modals in it. For example, if some request was failed then I want to show an error modal, if some request was successful then I want to show a success modal.
I currently do it as following which I think is bad practice:
...
export default function SomeSampleScreen(props) {
const [errorModalVisible, setErrorModalVisible] = useState(false);
const [errorMessage, setErrorMessage] = useState('');
const [successModalVisible, setSuccessModalVisible] = useState(false);
const [successMessage, setSuccessMessage] = useState('');
function showError(message) {
setErrorMessage(message);
setErrorModalVisible(true);
}
function showSuccess(message) {
setSuccessMessage(message);
setSuccessModalVisible(true);
}
return (
<>
<ErrorModal
visible={errorModalVisible}
onClose={() => {
setErrorModalVisible(false);
}}>
{errorMessage}
</ErrorModal>
<SuccessModal
visible={successModalVisible}
onClose={() => {
setSuccessModalVisible(false);
}}>
{successMessage}
</SuccessModal>
<View>
...
</View>
</>
);
}
You could just condense it into one object:
export default function SomeSampleScreen(props) {
const [modalState, setModalState] = useState({state: ''});
function showError(message) {
setModalState({state: "error", message});
}
function showSuccess(message) {
setModalState({state: "success", message});
}
return (
<>
<ErrorModal
visible={modalState.state === "error"}
onClose={() => {
setModalState({state: ''});
}}>
{modalState.message}
</ErrorModal>
<SuccessModal
visible={modalState.state === "success"}
onClose={() => {
setModalState(false);
}}>
{modalState.message}
</SuccessModal>
<View>
...
</View>
</>
);
}
UDPATE After clarifying what the actual question is, here is a good way to do it. Create a Context:
const ModalContext = React.createContext({status: "", message: ""});
Add the context and the modals somewhere up in your tree:
constructor(props) {
super(props);
this.setModal = (modalState) => {
this.setState(state => ({...state, ...modalState}));
};
this.state = {
status: "",
message: "",
setModal: this.setModal,
};
}
return <ModalContext.Provider value={this.state.modalState}>
<RestOfApp />
<Modals/>
</ModalContext.Provider>
The Modals would be similar to what you postet:
export default function SomeSampleScreen(props) {
const modalState = useContext(ModalContext);
function showError(message) {
modalState.setModal({state: "error", message});
}
function showSuccess(message) {
modalState.setModal({state: "success", message});
}
return (
<>
<ErrorModal
visible={modalState.state === "error"}
onClose={() => {
modalState.setModal({state: ''});
}}>
{modalState.message}
</ErrorModal>
<SuccessModal
visible={modalState.state === "success"}
onClose={() => {
modalState.setModal(false);
}}>
{modalState.message}
</SuccessModal>
<View>
...
</View>
</>
);
}