根据按钮单击反应js渲染differnet组件

时间:2020-04-29 04:55:12

标签: reactjs

所以我有这种逻辑,即用户单击一个按钮,然后根据所单击的按钮呈现不同的组件,我想知道是否有更好的方法来实现此逻辑

function Test(props) {

    const [component, setComponent] = useState("createPatient")
    const [rendered, setRendered] = useState()

    function clickHandler(component) {
        switch (component) {
            case "createPatient":
                setRendered(<PatientForm/>)
                break
            case "findPatient":
                setRendered(<FindPatient/>)
                break
            case "patientsList":
                setRendered(<PatientListTable/>)

        }
    }

    return (
        <div>

            <button onClick={() => clickHandler("createPatient")}>Create Patient</button>
            <button onClick={() => clickHandler("findPatient")}>Find Patient</button>
            <button onClick={() => clickHandler("patientsList")}>Patients List</button>


            { rendered  }
        </div>
    );
}

export default Test;

3 个答案:

答案 0 :(得分:2)

这里所有其他答案都是正确的,并且适合您的用例。我想更进一步,向您介绍代码拆分。不必要,但是您可以随时尝试。

当前,您正在加载Test组件时立即加载所需的所有组件。如果将来导入的组件变大或变复杂,则初始渲染速度可能会变慢。

代码拆分允许您将代码拆分为小块,然后按需加载。

这里是工作中的sandbox

import React, { useState } from "react";

function Test() {
  const [component, setComponent] = useState(null);

  const LoadComponent = async location => {
    const { default: component } = await import(`./components/${location}`);
    setComponent(component);
  };

  return (
    <div>
      <h1>Click the button to proceed</h1>
      <button onClick={() => LoadComponent("PatientForm")}>
        Create Patient
      </button>
      <button onClick={() => LoadComponent("FindPatient")}>
        Find Patient
      </button>
      <button onClick={() => LoadComponent("PatientListTable")}>
        Patients List
      </button>
      {component}
    </div>
  );
}

export default Test;

如果您使用的是最新版本的React,则可以使用React.lazy。您还需要用Suspense包装这个惰性组件。您可以像上面那样修改上面的代码,以使用React.lazy加载组件。

import React, { useState, Suspense } from "react";

const LoadComponent = location => {
    const Component = React.lazy(() => import(`./components/${location}`));
    setComponent(<Component />);
  };

return <Suspense fallback={<div>Loading...</div>}>{component}</Suspense>

始终考虑如何向用户交付最少数量的JavaScript。

答案 1 :(得分:0)

可用的其他逻辑大致相似,最终结果并没有太大不同,主要是风格上的,可读性也有所不同。这是两种替代方法;

function Test(props) {
const [index, setIndex] = useState(0);
const components = [<PatientForm/>, <FindPatient/>, <PatientListTable/>];

return (
  <div>
     <button onClick={() => setIndex(0)}>Patient Form</button>
     <button onClick={() => setIndex(1)}>Find Patient</button>
     <button onClick={() => setIndex(2)}>Patients List</button>
    {components[index]}
  </div>
)

或使用布尔方法渲染组件;像这样的东西

function Test(props) {
const [step, setStep] = useState(0);

return (
  <div>
     <button onClick={() => setStep(0)}>Patient Form</button>
     <button onClick={() => setStep(1)}>Find Patient</button>
     <button onClick={() => setStep(2)}>Patients List</button>
     {step == 0 && <PatientForm/>}
     {step == 1 && <FindPatient/>}
     {step == 2 && <PatientListTable/>}
  </div>
)

您明白了

答案 2 :(得分:0)

无需使组件保持状态,而是可以使用条件直接渲染它们。

function Test(props) {

    const [component, setComponent] = useState("createPatient")

    function clickHandler(component) {
        switch (component) {
            case "createPatient":
                setComponent('createPatient)
                break
            case "findPatient":
                setComponent('findPatient')
                break
            case "patientsList":
               setComponent('patientsList')

        }
    }

    return (
        <div>

            <button onClick={() => clickHandler("createPatient")}>Create Patient</button>
            <button onClick={() => clickHandler("findPatient")}>Find Patient</button>
            <button onClick={() => clickHandler("patientsList")}>Patients List</button>

         {component === 'createPateient' && <PatientForm/>}
         {component === 'findPatient' && <FindPatient/>}
         {component === 'patientsLis' && <PatientListTable/>}
           
        </div>
    );
}

export default Test;