首页 > 解决方案 > 寻找一种巧妙的方式来动态渲染多个子组件

问题描述

我有一个由 a<Header>和 a组成的模态组件<Content>

我希望两个孩子都<Header>可以<Content>根据给定的值(“模态类型”)动态呈现。

我的第一个直觉是创建一个存储模态组件的对象,例如:

export const useModalDetails = (onClose = () => {}) => {
    const [ modalDetails, setModalDetails ] = useMergeState({
        Header: () => <div/>,
        Content: () => <div/>,
        onClose,
    });
    return [modalDetails, setModalDetails];
};

然后是一个根据值类型设置模态详细信息的函数:

const onChangeModalType = (type) => {
  if (type === 'type1') {
   setModalDetails({
     Header: () => <div>Modal Header Type 1</dov>,
     Content: () => <div>Modal Content Type 1</div>,
     open: true

   })
  } else if (type === 'type2') {
   setModalDetails({
     Header: () => <div>Modal Header Type 2</dov>,
     Content: () => <div>Modal Content Type 2</div>,
     open: true
   })
  }
}

然后我可以在组件中使用 react-hook <Modal>

import SemanticModal from 'semantic-ui-react'

const Modal = () => {

 const [ modalDetails, setModalDetails ] = useMergeState({
        Header: () => <></>,
        Content: () =>  <></>,
        open: false,
    });
    return [modalDetails, setModalDetails];
    
  onChangeModalType('type2')

 return (
  <>
  <SemanticModal
     Header={modalDetails.Header}
     Content={modalDetails.Content}
     open={modalDetails.open}
  />
  <button onClick={() => onChangeModalType('type1')}>load type 1</button>
   <button onClick={() => onChangeModalType('type2')}>load type 2</button>
  </>
 )
}

请记住,我有 12 种不同类型的内容,以及 a 的标题<Modal>,这意味着if, else每种内容有 12 条语句。

你知道我怎样才能以一种更聪明、更聪明、更易读、更可维护的方式来开发它吗?

标签: reactjsreact-hooks

解决方案


如果您决定拥有一个基于状态/道具切换行为的单独模态组件,您可以像这样处理它:

const modals = {
  type1: {
    Header: <div>Modal1 Header</div>,
    Content: <div>Modal1 Content</div>,
    open: true,
  },
  type2: {
    Header: <div>Modal2 Header</div>,
    Content: <div>Modal2 Content</div>,
    open: true,
  },
};

const Modal = ({type}) => {
  const [modalType, setModalType] = useState(type);
  const { Header, Content, open } = modals[modalType];

  return (
    <>
      <SemanticModal
        Header={Header}
        Content={Content}
        open={open}
      />
    </>
  );
};

要考虑的另一种方法是创建一个可重用的BaseModal组件,您可以将其扩展到每个用例的单独组件中:

const BaseModal = ({ Header, Content, open }) => {
  return (
    <>
      <SemanticModal Header={Header} Content={Content} open={open} />
    </>
  );
};

const Modal1 = () => {
  return (
    <BaseModal
      Header={<div>Modal1 Header</div>}
      Content={<div>Modal1 Content</div>}
      open={true}
    />
  );
};

这种模式的好处是您仍然可以共享所有模式的共同元素,同时有选择地注入需要不同的部分


推荐阅读