【问题标题】:React-native formik - very slow performance with several fieldsReact-native formik - 多个字段的性能非常慢
【发布时间】:2023-01-12 18:22:30
【问题描述】:

我有一个问题,如果有多个字段,我的 formik 的性能会非常慢,它在 4 个字段中工作相对较慢,但它是可以接受的,但因为我们有 12 个字段,它的工作速度肯定太慢了。标记复选框大约需要 3-4 秒。问题是每次点击似乎都会重新呈现所有字段。我试图找到修复它的方法,其中一个选项是使用 FastField,但不幸的是它似乎不适用于 RN。知道如何让它工作得更快并且不重新渲染不必要的未更改字段吗?

所以基本上每个字段包含两件事:

  • 检查是否应禁用文本字段的复选框
  • 用户可以通过键盘或按钮输入一些数量的文本字段

它看起来像这样:

<Formik innerRef={formRef} initialValues={updatedValues} validationSchema={validationSchema} onSubmit={() => {}}>
      <Box>
        <CheckboxWithInputControls
          checkboxFieldName={'addedPipeline'}
          inputFieldName={'pipeline'}
          label={t('additionals.pipeline')}
          step={amount}
        />

        <Divider />

        <CheckboxWithInputControls
          checkboxFieldName={'addedHose'}
          inputFieldName={'hose'}
          label={t('additionals.hose')}
          step={amount}
        />

        .....
        <FormChangesListener setIsValid={setIsValid} setValues={setValues} />
      </Box>
    </Formik>


export const CheckboxWithInputControls = ({
  checkboxFieldName,
  inputFieldName,
  label,
  step,
  inputRightElement
}: CheckboxWithInputControlsProps) => {
  const [{ value: isChecked }, _meta, { setValue }] = useField(checkboxFieldName)

  return (
    <Box mb="4">
      <Box my="2" p="2" bg={isChecked ? 'blue.100' : 'white'} borderRadius="md">
        <Checkbox
          value={checkboxFieldName}
          isChecked={isChecked}
          onChange={() => setValue(!isChecked, false)}
        >
          {label}
        </Checkbox>
      </Box>
      <Box pl="10">
        <NumberInputWithControls
          controlName={inputFieldName}
          disabled={!isChecked}
          step={step}
          inputRightElement={inputRightElement}
        />
      </Box>
    </Box>
  )
}

const FormChangesListener =({ setIsValid, setValues }:AdditionsFormProps) => {
  const { values, isValid } = useFormikContext()
  useEffect(() => {
    setIsValid(isValid)
    setValues(values as FormProps)
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [values, isValid])
  return null
}

Why-do-you-render 响应:

 GROUP    CheckboxWithInputControls
 LOG    {"CheckboxWithInputControls": [Function CheckboxWithInputControls]} Re-rendered because of hook changes:
 GROUP      [hook useContext result]
 LOG      different objects that are equal by value.

【问题讨论】:

    标签: react-native formik


    【解决方案1】:

    查找问题的最佳方法是使用https://github.com/welldone-software/why-did-you-render 或 Flipper Flamegraph Tool。如果您在大量不必要的重新渲染中发现该问题,您就可以了解在哪里修复它。 从您的实现中,首先,尝试从 onSubmit={() =&gt; {}} 中删除匿名函数,因为它会导致在每个渲染周期中重新渲染所有子元素。还尝试为您的自定义组件添加记忆 CheckboxWithInputControlsmemo(CheckboxWithInputControls)

    【讨论】:

    • 我需要像这样保持 onSubmit,因为它是强制性属性,否则打字稿会冲我大喊大叫,我在不同的地方处理提交,所以这就是为什么我把它留空,而且我已经尝试用备忘录来包含我的组件,但它没有带来任何影响。我会试试这个“你为什么渲染”,让我们看看它告诉我什么
    • 在这里让我们知道结果,保持onSubmit不是问题,问题是它是匿名函数,尝试提取它
    • 当我使用 memo 时它什么都不显示,没有 memo 它会给我更新的问题中的信息,我想这是我的 formListener 引起的但仍然没有它我无法更新值
    猜你喜欢
    • 2019-12-05
    • 2017-11-07
    • 2021-10-03
    • 1970-01-01
    • 2021-05-24
    • 2016-12-06
    • 1970-01-01
    • 2018-04-01
    • 2014-06-05
    相关资源
    最近更新 更多