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