Javascript 在React中重用组件逻辑

Javascript 在React中重用组件逻辑,javascript,reactjs,Javascript,Reactjs,我有一个更一般/概念性的问题-在React中,如何创建一个可以构建的组件。让我解释一下: 假设我们有一个,其中有姓名、年龄和地址的文本字段。该应用程序可供平民和警察使用。如果它由警官使用,我们还希望有一个介于年龄和地址之间的部门编号。医生也可以使用它,在这种情况下,我们需要在name和age之间添加一个specialization字段。一种方法是使用,然后复制所有内容(啊!)。另一种方法是使用HOC,但我不知道如何准确地进行。还有其他想法吗?您可以添加一个布尔值来显示或隐藏组件中的特定信息,这样

我有一个更一般/概念性的问题-在React中,如何创建一个可以构建的组件。让我解释一下:


假设我们有一个
,其中有
姓名
年龄
地址
的文本字段。该应用程序可供平民和警察使用。如果它由警官使用,我们还希望有一个介于
年龄
地址
之间的
部门编号
。医生也可以使用它,在这种情况下,我们需要在
name
age
之间添加一个
specialization
字段。一种方法是使用
,然后复制所有内容(啊!)。另一种方法是使用HOC,但我不知道如何准确地进行。还有其他想法吗?

您可以添加一个布尔值来显示或隐藏组件中的特定信息,这样您就可以重用它。

您可以添加一个布尔值来显示或隐藏组件中的特定信息,这样您就可以重用它。

我看不出高阶组件作为一个整体如何帮助解决这个问题HOC实际上只能注入道具和行为,但它们不能改变UI,即JSX

React的设计考虑到了组合,因此您应该抽象地思考构成“PersonalInfo”组件的UI元素,即可以创建哪些较小的构建块组件来组成较大的组件。根据您提供的信息,我猜您有一个字段/属性集合,这些字段/属性组合在一起表示一个人的“个人信息”

从这里您可以选择几个方向之一:

  • 使用较小的构建块组件构建不同的相似组件,这些组件恰好共享许多相似的UI元素,即您的
    PersonalInfo
    PolicyOfficerPersonalInfo
    组件。Pro是指每个组件都有一个特定用途,但con是指如果多个组件共用的任何字段需要更新,则可能需要对其全部进行跟踪(如果组合构建块设计良好,则需要进行缓解)
  • 创建一个通用的“个人信息”容器,该容器显示一组特定的信息,并公开道具以有条件地渲染额外字段。赞成者:一个单一的组件,但反对者是我所说的道具爬行,如果没有适当的整理/维护,可能会失控,最终你会得到一个整体组件,它可以做任何事情(也许好,也许不太好)
  • 创建包装容器以控制总体布局,但通过
    子对象
    道具呈现子对象。这里的优点是你得到了你想把UI放进去的容器,然后在设计时决定要显示哪些子对象。将其视为超级div,即
    {props.children}
    。一个骗局可能是,你没有一个预制的专门组件躺在周围,只是在某处插入

  • 我不认为高阶组件能够/能够帮助解决这个问题,因为HOC实际上只能注入道具和行为,但它们不能改变UI,即JSX

    React的设计考虑到了组合,因此您应该抽象地思考构成“PersonalInfo”组件的UI元素,即可以创建哪些较小的构建块组件来组成较大的组件。根据您提供的信息,我猜您有一个字段/属性集合,这些字段/属性组合在一起表示一个人的“个人信息”

    从这里您可以选择几个方向之一:

  • 使用较小的构建块组件构建不同的相似组件,这些组件恰好共享许多相似的UI元素,即您的
    PersonalInfo
    PolicyOfficerPersonalInfo
    组件。Pro是指每个组件都有一个特定用途,但con是指如果多个组件共用的任何字段需要更新,则可能需要对其全部进行跟踪(如果组合构建块设计良好,则需要进行缓解)
  • 创建一个通用的“个人信息”容器,该容器显示一组特定的信息,并公开道具以有条件地渲染额外字段。赞成者:一个单一的组件,但反对者是我所说的道具爬行,如果没有适当的整理/维护,可能会失控,最终你会得到一个整体组件,它可以做任何事情(也许好,也许不太好)
  • 创建包装容器以控制总体布局,但通过
    子对象
    道具呈现子对象。这里的优点是你得到了你想把UI放进去的容器,然后在设计时决定要显示哪些子对象。将其视为超级div,即
    {props.children}
    。一个骗局可能是,你没有一个预制的专门组件躺在周围,只是在某处插入

  • 有很多方法可以使用,但我只是将组件创建为CommonTextFields,并用于重复部分。这样,即使您有一定程度的代码重复,也更具可读性和可维护性

    const PageA = () => {
      // do your validation and fetch logic here
    
      return (
        <>
          <CommonFields age={age} name={name} value={address} />
          <FieldA value={fieldA} />
        </>
      );
    };
    
    constpagea=()=>{
    //在这里执行验证和获取逻辑
    返回(
    );
    };
    
    constpageb=()=>{
    //在这里执行验证和获取逻辑
    返回(
    );
    };
    
    但如果您坚持非呈现部分(验证/获取逻辑等)不要重复(我认为这是一个坏主意,因为它会破坏可维护性)。有HOC和renderProps选项;您也可以通过customHooks支持这一点。但在这种情况下,您需要找到一种方法,将未重复的部分包含到获取和验证逻辑中

    // Really looks so messy and not scalable
    // Yhis is only one field, imagine for array of fields
    const CommonFieldsHOC => ( Field, fieldName, validationFunc ) => ( props ) => {
    
      const [extraField, setExtraField] = useState()
      const commonValidation = () => {}
    
      // Find a way to include extraFields logic to validation and Fetch
      handleSubmit = () => {
        const isCommonFieldsValid = commonValidation()
        const isFieldValid = validationFunc(extraField)
        if(isFieldValid && isCommonFieldsValid) {
          submitFunction({ name, age, address,
            [fieldName]: extraField
          })
        } else {
          // give some warning
        }
      }
    
      return (
        <>
          <Name value={name} />
          <Age value={age} />
          <Address value={address} />
          <Field value={extraField} onChange={extraField} />
          <Button onClick={handleSubmit}>
        </>
      )
    };
    
    //看起来真的很乱而且不可扩展
    //Yhis只是一个字段,想象一下字段数组
    常数
    
    // Really looks so messy and not scalable
    // Yhis is only one field, imagine for array of fields
    const CommonFieldsHOC => ( Field, fieldName, validationFunc ) => ( props ) => {
    
      const [extraField, setExtraField] = useState()
      const commonValidation = () => {}
    
      // Find a way to include extraFields logic to validation and Fetch
      handleSubmit = () => {
        const isCommonFieldsValid = commonValidation()
        const isFieldValid = validationFunc(extraField)
        if(isFieldValid && isCommonFieldsValid) {
          submitFunction({ name, age, address,
            [fieldName]: extraField
          })
        } else {
          // give some warning
        }
      }
    
      return (
        <>
          <Name value={name} />
          <Age value={age} />
          <Address value={address} />
          <Field value={extraField} onChange={extraField} />
          <Button onClick={handleSubmit}>
        </>
      )
    };
    
    const MyExtraField = () => <MyExtraField />
    const validateMyExtraField = (value) => value > 0 
    
    const MyForm = CommonFieldsHOC(MyExtraField, 'MyExtraField', validateMyExtraField )
    
    const Page = () => {
      return <>
        <MyForm />
      </>
    }