Reputation: 969
I have a Modal component which is a popup window. I need to set different components to the bodyContainer.
<Modal
show={this.props.first.showModal}
size={this.props.first.sizeModal}
bodyContainer={this.props.first.modalBodyContainer}
/* bodyContainer={<Mail {...this.props}/>} */
onClose={this.props.firstActions.onCloseModalHome}
/>
As I understand the redux philosophy I can do it like this
// Search Patient actions
export const onSearchPatient = (ur, token) => dispatch => (
callToApiWithToken(`patient/by/ur/${ur}`, token)
.then(response =>
((response.data === null) ? dispatch(onSearchPatientNotFound(ur)) : dispatch(onSearchPatientFound(response.data))),
)
.catch(error => ({ type: psActions.ON_SUBMIT_ERROR }))
);
export const onSearchPatientFound = createAction(psActions.ON_SEARCH_PATIENT_FOUND);// data
export const onSearchPatientNotFound = createAction(psActions.ON_SEARCH_PATIENT_NOT_FOUND);
//Reducer
case psActions.ON_SEARCH_PATIENT_FOUND:
return {
...state,
showModal: true,
modalBodyContainer: <PatientDetails {...action.payload} />,
};
case psActions.ON_SEARCH_PATIENT_NOT_FOUND:
return {
...state,
error: true,
errorMsg: <div>The Patient <strong>{action.payload}</strong> is not in the system</div>,
};
But my colleague arguing that this is a bad practice. Specifically I'm talking about
modalBodyContainer: <PatientDetails {...action.payload} />
It is possible to relocate render logic to the Modal but in this case I need to create a switch for all possible components.
What is the right way to do this?
Edited I have two ideas how to do this. What is the best to use?
//Action
export const setModalBody = createAction(psActions.SET_MODAL_BODY);//component
//Reducer
case psActions.SET_MODAL_BODY:
return {
...state,
showModal: true,
modalBodyContainer: action.payload />,
};
//Usage
onClick={() => searchPatient.length > 0 && onSearch(searchPatient, token).then(patientFound && setModalBody(<Patient {...props} />)
OR
const Modal = ({...}) => (
{{
//Something like this
//switch based on prop.bodyComponentType
//in this case I need to import all possible components to the Modal
sectionA: (
<SectionAComponent />
),
sectionB: (
<SectionBComponent />
),
sectionC: (
<SectionCComponent />
)
}[section]}
)
Edited 2 It is not about redux actions, it's about a component rendering inside hoc related to actions.
Upvotes: 1
Views: 238
Reputation: 6427
Your coworker is right.
The philosophy of Redux/React is largely around separation of concerns and making things loosely coupled but highly cohesive. For this situation, that means that your action should not know anything about the component it will cause to render (loosely coupled), but will be a complete definition of the result of your api call (highly cohesive).
I would have both of your reducer functions modify the same attribute of the redux state. Afterall, they represent the same piece of data, just with different values. One represents a success, and the other a failure. So I would have them both modify patientFoundStatus
and provide it a value (perhaps using http codes, or a success
/failure
constant defined elsewhere). Then use this value to determine the output of your modal.
So why is this better?
Well for a couple of reasons. The most important is to consider how your code would need to be modified if, later on, this action needed to produce a different (additional) result in the view. Let's say that it is now used to pre-populate a form with the patient's information. How would your code need to change?
Given the code you have above, it would need to be entirely rewritten or duplicated. The modal body components would be completely irrelevant to this new feature, and the "success/failure" information (and patient information) needed would need to be added.
But consider if these actions only returned the data relevant to the view. Well now, what you do with that data is up to you. The reducers and actions could remain entirely unchanged, and you could merely use that pre-existing slice of state to impact a new section of your app.
That's one of the biggest advantages to react/redux when used correctly. Over time, what you end up creating is a flexible toolbox that makes adding new features trivial, because all the plumbing is well in place and wholly distinct from how it is utilized. Low coupling. High cohesion.
Upvotes: 3