如何使用React / Redux渲染组件(正确的方法)?

时间:2017-09-12 16:24:35

标签: javascript reactjs redux react-redux

我有一个Modal组件,它是一个弹出窗口。我需要为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}
/>

据我了解redux哲学,我可以这样做

// 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>,
  };

但我的同事认为这是一种不好的做法。特别是我在谈论

modalBodyContainer: <PatientDetails {...action.payload} />

可以将渲染逻辑重定位到Modal,但在这种情况下,我需要为所有可能的组件创建一个开关。

这样做的正确方法是什么?

被修改 我有两个想法如何做到这一点。什么是最好用的?

//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} />)

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]}
)

已编辑2 它不是关于redux动作,而是关于内部与动作相关的组件呈现。

1 个答案:

答案 0 :(得分:3)

你的同事是对的。

Redux / React的理念主要围绕关注点的分离,使事物松散耦合,但具有高度凝聚力。对于这种情况,这意味着您的操作不应该知道它将导致呈现的组件(松散耦合),但将是您的api调用结果的完整定义(高度内聚)。

我希望你的两个reducer函数都修改与redux状态相同的属性。毕竟,它们代表相同的数据,只是具有不同的值。一个代表成功,另一个代表失败。所以我希望他们都修改patientFoundStatus并提供一个值(可能使用http代码,或其他地方定义的success / failure常量)。然后使用此值确定模态的输出。

为什么这样更好?

好吧有几个原因。最重要的是考虑如果稍后需要在视图中生成不同(附加)结果所需的操作,则需要如何修改代码。让我们说它现在用于预先填写患者信息的表格。您的代码需要如何更改?

鉴于您上面的代码,它需要完全重写或复制。模态的主体组件与这个新功能完全无关,并且&#34;成功/失败&#34;需要添加所需的信息(和患者信息)。

但请考虑这些操作是否仅返回与视图相关的数据。那么现在,你对这些数据的处理取决于你。 Reducer和actions可以保持完全不变,并且您只能使用预先存在的状态片来影响应用的新部分。

正确使用时,这是做出反应/减少的最大优势之一。随着时间的推移,您最终创建的是一个灵活的工具箱,这使得添加新功能变得微不足道,因为所有的管道都很好地完全不同于它的使用方式。低耦合。高凝聚力。