如何将组件作为道具传递并有条件地渲染它?

How to pass component as a prop and render it conditionally?

我这里有一个组件,它获取一个 ID 号并检查该 ID 号是否存在于数据库中。如果它存在,它应该呈现一个组件,如果不存在则显示错误消息。为我应该如何写而苦苦挣扎,感谢任何帮助。

function PatientIDInput({component}) {
  const [patientID, setPatientID] = useState('');
  const [errorMessage, setErrorMessage] = useState('');
  const [showComponent, setShowComponent] = useState(false);
  const [patientInformation, setPatientInformation] = useState('');

  const handleChange = (e) => {
    // some input change handling
  }

  const handleSubmit = (e) => {
    e.preventDefault();

    Physician.fetchPatientData(patientID)
      .then(res => {
        if (res.status === 200) {
            // show component if patient exists
        }
      })
      .catch(error => {
        if (error.response.status) {
          // set error if not
        }
      })
  }

  return (
    <>
    <form onSubmit={handleSubmit}>
               // some UI code for user's input
    </form>

    { showComponent 
      ? {Component patientInformation={patientInformation}} />  // this is where I'm 
                   struggling with the syntax. How should I write the logic? I want to pass
                   some props to the component too.
      : null}
    </>
  );
}

export default PatientIDInput;

以下是我最常用的一些模式。

传递“React 组件”

function PatientIDInput({Component}) {
  // skip
  return (
    <>
    <form onSubmit={handleSubmit}>
               // some UI code for user's input
    </form>

    { showComponent 
      ? <Component patientInformation={patientInformation} />
      : null}
    </>
  );
}

export default PatientIDInput;
const Sample = ({ patientInformation }) => <div>{patientInformation}</div>
<PatientIDInput Component={Sample} />

将“渲染函数”作为子项传递

function PatientIDInput({children}) {
  // skip
  return (
    <>
    <form onSubmit={handleSubmit}>
               // some UI code for user's input
    </form>

    { showComponent 
      ? children({ patientInformation  })
      : null}
    </>
  );
}

export default PatientIDInput;
const Sample = ({ patientInformation }) => <div>{patientInformation}</div>
<PatientIDInput>
  {({ patientInformation }) => <Sample patientInformation ={patientInformation} />}
</PatientIDInput>

将“React 元素”作为子元素传递

function PatientIDInput({children}) {
  // skip
  return (
    <>
    <form onSubmit={handleSubmit}>
               // some UI code for user's input
    </form>

    { showComponent 
      ? React.cloneElement(children, { patientInformation  })
      : null}
    </>
  );
}

export default PatientIDInput;
const Sample = ({ patientInformation }) => <div>{patientInformation}</div>
<PatientIDInput>
  <Sample/>
</PatientIDInput>

您可以使用

React.cloneElement(
  element,
  [config],
  [...children]
)

克隆并 return 使用元素作为起点的新 React 元素。配置应该包含所有新的 props、key 或 ref。生成的元素将具有原始元素的道具,新道具将浅层合并。新的 children 将替换现有的 children。如果配置中不存在键和引用,则将保留原始元素中的键和引用。

例子

import React from "react";

function Child(props) {
  return <div>{props.name}</div>;
}

function SomeOtherComponent(props) {
  return (
    <>
      {React.cloneElement(props.component, {
        someFunction: () => {
          console.log("inside callback");
        },
        name: "Ganesh",
      })}
    </>
  );
}

function App() {
  return (
    <div>
      Hi
      <SomeOtherComponent component={<Child />}></SomeOtherComponent>
    </div>
  );
}

与其将组件作为 props 传递,不如直接在 PatientIdInput 组件中导入组件,并将 patientInformation 作为 props 传递给它,如下所示:

**Import your Component Here**

function PatientIDInput({component}) {
  const [patientID, setPatientID] = useState('');
  const [errorMessage, setErrorMessage] = useState('');
  const [showComponent, setShowComponent] = useState(false);
  const [patientInformation, setPatientInformation] = useState('');

在return部分:

 return (
   <>
    <form onSubmit={handleSubmit}>
           // some UI code for user's input
    </form>

  { showComponent 
    ? <ImportedComponent patientInformation={patientInformation}/>
  : null}
</>
  );
}

export default PatientIDInput;