如何在React Final Form之外管理状态?

时间:2019-07-22 17:10:03

标签: javascript reactjs react-hooks react-final-form final-form

我想将我的React Final Form的状态存储在某个地方。现在,这在React Hook中。我目前正在使用useMethods,类似于useState

我当前拥有的表单是一个多步骤过程的一部分,当我导航到该表单所在的另一个页面时,它会被卸载(当然)。重新安装后,我想为表单提供初始值(可用here)。

问题在于,当我的状态改变时,表单会重新呈现,而我总是陷入无休止的循环,因为:

  • FormSpy以表格形式存储更改
  • 状态已更改
  • 表格已重新呈现
  • FormSpy以表格形式存储更改
  • 依此类推...

我还有一个问题,当提供初始值时,不会填充字段状态(脏,被触摸等),因此重新安装时表单看起来很奇怪,因为某些标签与元字段相关联。似乎我们需要某种方式来存储所有表单状态,不仅值包含组件Form的值可以卸载并重新安装 n 次数。

我想要什么:

  • 更改为立即以我的状态存储
  • 重新渲染以某种方式记住(如有需要,我可以将其存储在自己的状态中)

我的出发点是看Auto-save with Debounce(尽管我不需要去抖动,因为我将其存储在本地)。

处理此问题的最佳方法是什么?

1 个答案:

答案 0 :(得分:0)

我刚遇到一个类似的问题,并且设法创建一个装饰器,该装饰器会记住触摸到的(或任何其他字段状态),然后在再次装入该字段时重新应用该状态。一个主要问题是,这导致闪烁,因为在安装时未渲染该字段,然后通知装饰器,然后将该字段渲染为触摸。

一些示例代码(未经测试):

function decorator(form) {
  const storedTouched = {};
  return form.subscribe(({touched}) => {
    for(const field of Object.keys(touched)) {
      if(touched[field]) {
        storedTouched[field] = true;
      }
    }
    for(const field of Object.keys(storedTouched)){
      if(touched[field] === false) { // check against false since unregistered fields are undefined
        form.mutators.setFieldTouched(field, true);
      }
    }
  }, {touched: true});
}

您还可以公开storedTouched以允许设置触摸的任何字段,而不仅仅是已安装/注册的字段。 (例如,将其初始化为上次已触摸的字段)