【问题标题】:How to render a component to prop with React/Redux (The right way)?如何使用 React/Redux 渲染组件来支持(正确的方法)?
【发布时间】:2017-09-12 16:24:34
【问题描述】:

我有一个模态组件,它是一个弹出窗口。我需要为 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 操作,而是关于在 hoc 中与操作相关的组件渲染。

【问题讨论】:

  • @lux 我不这么认为。它不是关于动作,而是关于组件渲染以及如何基于 redux 哲学来实现它。如果您能提出正确的方法,请告诉我
  • 不要使 body 动态,只需发出一个呈现特定模态的动作。由于您已经有了一个通用的 Modal 组件,因此无需变得聪明并更换 body。
  • @lux 所以 setModalBody 动作是个好主意,对吧?
  • 这样的事情怎么样:gist.github.com/mikechabot/975eab040ca70e36bf84579453d530e5 你的 redux 操作有一个 modalType 指的是一个完全构建的模态,而你只需传入该模态所需的 props ,而不是它的整个 DOM 主体。

标签: javascript reactjs redux react-redux


【解决方案1】:

你的同事是对的。

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

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

那么为什么这样更好呢?

有几个原因。最重要的是考虑如果稍后需要此操作在视图中产生不同的(附加)结果,您的代码将需要如何修改。假设它现在用于使用患者信息预填充表单。您的代码需要如何更改?

鉴于您上面的代码,它需要完全重写或复制。模态体组件将与此新功能完全无关,需要添加所需的“成功/失败”信息(和患者信息)。

但请考虑这些操作是否仅返回与视图相关的数据。现在,您如何处理这些数据取决于您自己。 reducer 和操作可以完全保持不变,您可以只使用该预先存在的状态片段来影响应用程序的新部分。

这是正确使用 react/redux 的最大优势之一。随着时间的推移,您最终创建的是一个灵活的工具箱,它使添加新功能变得微不足道,因为所有管道都已安装到位并且与使用方式完全不同。低耦合。高凝聚力。

【讨论】:

  • 请看看我的更新。这样做的正确/最佳方法是什么
  • 我可能也不会这样做。如果这些模态用于不同的目的,则单个组件没有理由渲染每个模态。您真正想要的是创建一个“高阶组件”,为不同的“body”组件提供模态功能,并保持这些 body 组件去中心化。 facebook.github.io/react/docs/higher-order-components.html
  • 我对所有记录类型都有不同的 hoc 组件。从主页需要显示现有记录并在模态中单击显示填充的 hoc。将 hoc 包装到另一个 hoc 只是为了显示一个弹出窗口不是矫枉过正吗?
猜你喜欢
  • 2021-02-07
  • 2017-02-10
  • 2018-03-24
  • 1970-01-01
  • 1970-01-01
  • 2021-05-14
  • 1970-01-01
  • 2016-11-03
  • 2020-01-31
相关资源
最近更新 更多