React-native formik -多个字段的性能非常低

gcuhipw9  于 2023-01-14  发布在  React
关注(0)|答案(1)|浏览(160)

我有问题,如果有几个字段,我formik的性能非常慢,它的工作速度相对较慢,但它是可以接受的,但因为我们有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
}

你为什么要做出回应:

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

编辑:我做了它的工作,所以在这里我离开解决方案,也许它会对某人有用,或者也许有人将能够提供更好的一个,因为我个人不喜欢它,所以原来useField不知何故导致所有的形式被重新呈现。当我放弃了在CheckboxWithInputControls中的useField的想法,只是通过 prop 传递值,它工作得很好,在一个字段中的更改只使这一个字段被重新呈现。

{({ values, setFieldValue, touched, errors }) => (
        <Box>
          <CheckboxWithInputControls
            checkboxFieldName={'addedPipeline'}
            inputFieldName={'pipeline'}
            label={t('additionals.pipeline')}
            step={amount}
            value={values.addedPipeline}
            subValue={values.pipeline}
            setFieldValue={setFieldValue}
            touched={touched.pipeline}
            error={errors.pipeline}
          />
    )})
6yoyoihd

6yoyoihd1#

找到问题的最好方法是使用https://github.com/welldone-software/why-did-you-render或Flipper Flamegraph工具。如果你在很多不必要的重新渲染中发现了这个问题,你就可以知道该在哪里修复它。首先,从你的实现来看,尝试从onSubmit={() => {}}中删除匿名函数,因为它会导致在每个呈现周期中重新呈现所有子元素。还可以尝试使用memo(CheckboxWithInputControls)为自定义组件CheckboxWithInputControls添加内存

相关问题