【问题标题】:Reactjs functional component common logic extractionReactjs 功能组件常用逻辑抽取
【发布时间】:2021-09-26 06:46:38
【问题描述】:

我有一些功能组件和一些公共变量和函数。请看下文。

const Customer = () => {
   const [isReleased, setIsReleased] = useState(false)

   const release = () => {
        setIsReleased(true)
   }
}

const Order = () => {
   const [isReleased, setIsReleased] = useState(false)

   const release = () => {
        setIsReleased(true)
   }
}

从上面的代码片段可以看出,release() 函数有共同的逻辑。它访问组件的变量/函数。

有没有办法将这个release() 函数移动到一个公共文件中并从每个组件中导入它?

请注意release() 方法应该能够访问调用者的作用域变量和函数。

更新

下面是release()函数的实际内容。我已经把this. 表示它引用了调用者中的变量/函数。

const release = () => {
  if (action === "new") {
    history.push(`/customers/new`)
  } else if (action === "save") {
    (async () => {
      try {
        if (this.dataMode === "new") {
          this.setMessage()
          this.setFormStatus("updating")
          let _res = await this.customer_api_create(this.formData)
          if ((_res.status === 200) && (_res.data.status === "success")) {
            this.setFormStatus()
            history.replace({ pathname: `/customers/${_res.data.data[0].id}` })
          }
        } else if (this.dataMode === "edit") {
          this.setFormStatus("updating")
          this.setMessage()
          let _res = await this.customer_api_update(this.formData)
          if ((_res.status === 200) && (_res.data.status === "success")) {
            this.setFormStatus()
            this.setMessage({ type: "info", text: "Saved" })
            this.setFormData(_res.data.data[0])
          }
        }
      } catch (e) {
        this.openMessageBox({
          prompt: e.response.data.message,
          type: this.constants.app.MessageBoxType.MB_Error,
          buttons: this.constants.app.MessageBoxButton.MB_Ok,
          show: true,
          setResult: () => console.log(this.constants.app.MessageBoxResult.MB_Ok)
        })
        this.setFormStatus("updating_error")
      }
    })();
  } else if (action === "del") {
    this.openMessageBox({
      prompt: `{ "": ["Are you sure you want to delete context customer?"] }`,
      type: this.constants.app.MessageBoxType.MB_Warning,
      buttons: this.constants.app.MessageBoxButton.MB_YesNo,
      show: true,
      setResult: (val) => {
        this.openMessageBox({ show: false })
        this.setShouldRecordDeleted(val)
      }
    })
  }
}

【问题讨论】:

  • 我会建议 redux。
  • 可以isReleased 状态、setter 和 release 函数抽象到自定义挂钩中,但您最终会得到大约相同数量的代码这些都是如此简单的块。虽然您将状态和回调命名为相同,但它们真的不是相同的代码。你不能从 React 组件中抽象出状态。我认为任何试图使您的 sn-ps 中的代码“更加干燥”的尝试都会不必要地使其更复杂,更难使用和维护。正如我所说,看看下面的答案,你并没有真正减少任何代码。
  • @drew-reese 其实release() 方法有很多行代码。不仅仅是setIsReleased(true)。这就是为什么我想把它抽象出来。
  • 请分享更准确、更全面的代码表示。 stackoverflow.com/help/minimal-reproducible-example
  • @Pasi-D useReducer 可能也可以工作并且更容易实现/使用。 OP 并不真正需要全局状态,这更像是 redux 和 Context API 的用途。看起来这两个组件实际上只共享状态变量名称和实现。我们仍然确实需要来自 OP 的更完整、更全面的组件代码示例,以获得更好的上下文。

标签: javascript reactjs react-functional-component


【解决方案1】:

您可以在不同的文件中声明函数释放并将setIsReleased 方法作为参数传递

import {release} from 'release';  

const Customer = () => {
       const [isReleased, setIsReleased] = useState(false)
       release(setIsReleased)
    }

在你的 release.js 文件中

export const release = (setIsReleased) => {
   setIsReleased(true)
}

【讨论】:

  • 不幸的是,这是不切实际的,因为release() 方法将访问更多的变量和函数。它不仅仅是调用setIsReleased() 方法。我没有将它们包括在我的问题中以使其更简单。但我现在明白了,我没有提到 release() 有大约 30 行代码,从而误导了读者。
【解决方案2】:

也许回调可以解决问题,这个怎么样?

另一个文件.js

    const release = (param, setter) => {
        if (true){
            setter(true)
        }
    }

你的文件.js

    import {release} from "anotherfile"
    const Customer = () => {
       const [isReleased, setIsReleased] = useState(false)
       release([parameter],setIsReleased)
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-02
    • 2022-01-14
    • 1970-01-01
    相关资源
    最近更新 更多