首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Formik时对表单字段使用抽象

使用Formik时对表单字段使用抽象
EN

Stack Overflow用户
提问于 2022-05-27 07:55:29
回答 1查看 188关注 0票数 2

我使用formik作为一个库来处理表单数据。

对于某些字段,我希望使用不同的基础类型,例如,我使用decimal.js-light处理十进制值*。

因此,在我的表单值中,我希望用这个类型来表示我的十进制类型。但是,当用户输入时,它仍然应该将输入看作字符串而不是数字。一个典型的例子是,如果用户希望将"1000“更改为"2000",如果用户删除"1”并输入"2",则如果输入在输入时被视为数字,则该值将变为"20“。

我们还需要处理用户的区域设置(区域设置取决于用户所属的租户的国家,而不是浏览器设置)。

因此,在加载表单时,我需要将十进制转换为本地化字符串。当我提交表单时,我需要解析用户区域设置这并不是微不足道的中的字符串。

还有一些依赖的字段,例如,我有一个数量和数量字段-我们计算的总量为数量*数量(使用decimal.js)。因此,现在我有了本地化解析的规则,在提交、验证输入和计算总计时,都有三个不同的位置。

formik是否有处理您正在处理的数据类型的不同底层抽象的模式?

*我们使用decimal.js是因为JavaScript不处理十进制精度,例如0.1+0.2不等于0.3。对于许多情况,这并不重要,但在我的应用程序中,我需要十进制精度。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-28 20:56:54

最后,我们有三组数据类型:

  • 我们从服务器获得的数字,这些数字应该保存(如果需要以高精度保存,则以数字或字符串格式保存)
  • formikDecimal类型字段
  • 以及要表示给最终用户的格式化字符串。

数据的表示可以很容易地提取到单独的封装层。

formik的Field参数之一是component。您可以使用它创建一个单独的组件,该组件只对字段值进行播放,将其格式化为应有的格式,并将其显示给最终用户。因此,格式化的值将只存在于该组件中。它不会暴露在外面。有一个漂亮的库(反应-数字格式)可以以复杂的方式处理它。

这样做的方式如下:

代码语言:javascript
复制
import NumberFormat from 'react-number-format'
import { Field } from 'formik'

const FormattedPrice = () => {
  return <Field component={NumberFormat} thousandSeparator="," {/* ...otherProps */} />
}

或者:

代码语言:javascript
复制
import NumberFormat from 'react-number-format'
import { useField } from 'formik'

const FormattedPrice2 = () => {
  const [{value}] = useField('price')

  return (
    <NumberFormat
      thousandSeparator=","
      prefix="$"
      value={value}
      {/* ...otherProps */}
    />
  )
}

如果您使用material,那么它的TextInput组件也有一个支持component,您可以在这里传递自定义装饰器或使用现有的react-number-format解决方案。我想你应该会处理好所有的案子。文档是非常详尽的。

这意味着,您不需要管理格式化数据的实际状态,只需提供一些配置。

字符串本地化也是该装饰组件的责任。

在此之后,我们将在formik的上下文中获得原始值。剩下的就是编写一些映射器,将数字转换为Decimals,并将它们作为initialValues提供给formik,反之亦然--在验证数据之后,将Decimal映射到onSubmit中的某个位置。该部分可以提取为单独的助手类,以处理所有在一个地方,并使他的功能自我毁灭。该类的近似接口:

代码语言:javascript
复制
import Decimal from 'decimal.js-light'

type BackendResponseData = {
  price: number
  // other fields
}

type FormValues = {
  price: Decimal
  // other fields
}

interface DataConverter {
  storedDataToFormValues(storedData: BackendResponseData) => FormValues
  formValuesToStoredData(formValues: FormValues) => BackendResponseData
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72402215

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档