【问题标题】:Formik setValues() throws 'Too many re-renders' errorFormik setValues() 抛出“重新渲染过多”错误
【发布时间】:2021-06-20 16:30:57
【问题描述】:

我正在尝试使用setValues 在函数clearCurrentEntries 中仅清除Formik 表单中的一些键,但无论我做什么,我都会收到错误Too many re-renders. React limits the number of renders to prevent an infinite loop. 我也尝试调用clearCurrentEntriesshowInput 函数中,但无论我把它放在哪里,我都会得到相同的重新渲染超出错误。

  • 如何清除 Formik 状态下的某些值,但防止应用重新渲染次数过多而引发此错误?
const Container = () => {
  const emptyObj = {
    first_name: '',
    last_name: '',
    middle_name: '',
  }

  const clearCurrentEntries = (values, setValues) => {
    setValues({ ...values, ...emptyObj })
  }
  const showInput = (values) => {
    const msOptions = ['one', 'two', '']
    const ms = values?.status?.toLowerCase()
    const show = msOptions.every((option) => ms !== option)
    return show
  }

  return 
    <div>
      <Formik
        enabledReinitialize={true}
        initialValues={formStructure}
        onSubmit={handleSubmit}>
        {({ handleChange, handleSubmit, values, setFieldValue, setValues }) => {
          return (
            <Form onSubmit={handleSubmit} >
              <div className="form-content">
                <Form.Group>
                  <Form.Label>Status</Form.Label>
                  <Form.Control
                    as="select"
                    id={'status'}
                    name={'status'}
                    value={values?.status}
                    onChange={handleChange}>
                    <option value="">Select...</option>
                    {statusOptions.map((option) => (
                      <option key={option} value={option}>
                        {option}
                      </option>
                    ))}
                  </Form.Control>
                </Form.Group>
                {showInput(values) ? (
                  <CurrentInputs />
                ) : (
                  clearCurrentEntries(values, setValues)
                )}
            </Form>
          )
        }}
      </Formik>
    </div>
  )
}

export default Container

【问题讨论】:

    标签: reactjs formik next rerender


    【解决方案1】:

    如果我错了,请纠正我,但你的清除功能实际上清除了一个东西,而是添加了。

    const clearCurrentEntries = (values, setValues) => {
      setValues({ ...values, ...emptyObj })
    }
    

    你是 passint values - 你的对象中存在的所有值。还有一个方法setValues 设置整个对象的值。

    在接收所有内容的函数中,您正在执行setValues 函数并传入对象内所有当前可用的数据,并将其与emptyObj 对象数据相结合。

    在这一切之后,它会更新您的状态,从而重新渲染组件。但由于新值是相同的旧值 + 只是 emptyObj 对象,因此它不会删除不需要的值,因此它会触发执行完全相同逻辑的相同函数。

    通过知道函数作为values 得到什么,可以更容易地找出问题所在。但是,如果我的理论是正确的,只需用 showInput 评论该区域就应该停止抛出这个错误。如果是这样 - 我是对的。

    在这种情况下,可以通过简单的修复来完成一个简单的修复,而不是删除它,只是不要渲染它。

    {showInput(values) && <CurrentInputs />}
    

    如果您确实需要将其删除,那也可以完成,但遗憾的是不知道 values 是什么以及它是如何存储的,由于我的知识有限,我无法预测该做什么以及如何做。如果你想用values更新你的帖子

    这样做的目的是尝试确定问题出现的原因和位置。

    【讨论】:

    • setValues 函数通过在 Formik 状态下维护和更新适当的值来按预期工作。它只是在此过程中引发重新渲染错误。无论我是创建一个新的更新状态 obj 还是以上面 w/emptyObj 的方式更新值,都会发生相同的错误。
    • 该错误是由于它不断地重新渲染而引起的。这是由于状态不断更新而引起的。当状态更新时,它会导致组件重新渲染。如果在重新渲染时,状态再次更新 - 再次重新渲染。在您的情况下,重新渲染永远不会结束,这意味着每次重新渲染后,状态都会自动更新一次又一次。 values 在您的情况下是一个状态,setValues 设置值并触发重新渲染。 [1/3]
    • 并且该功能仅由clearCurrentEntries 方法触发,如您的示例所示。因此,为什么首先要假设这是问题所在。如果删除整个组件就解决了问题,那么触发重新渲染的唯一因素是clearCurrentEntries 中的setValues。所以我所期望的,并从代码中看到,clearCurrentEntries 不会清除触发渲染中if 语句的values 变量中的一个或多个值,因此每次重新渲染它都会进入if 声明一次又一次 [2/3]
    • 如果我的假设是正确的,注释掉{showInput(values) ? ( &lt;CurrentInputs /&gt; ) : ( clearCurrentEntries(values, setValues) )},并使show 始终为真,因此它会呈现您需要的内容,暂时将暂时解决它。如果是这样,那么修复clearCurrentEntries,正如我所提到的,将永远解决您的问题。请尝试一下,因为它最有可能是问题所在。我知道我可能写了一些东西,导致对“为什么”的误解,很可能是因为我的英语很糟糕,如果是这样的话 - 评论什么并错误地修复帖子(如果它解决了问题)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-24
    • 1970-01-01
    • 2023-01-13
    • 2023-03-31
    • 2020-12-30
    • 1970-01-01
    相关资源
    最近更新 更多