简体   繁体   English

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

[英]How do I manage state outside of React Final Form?

I want to store the state of my React Final Form somewhere.我想将我的 React Final Form 的状态存储在某处。 Right now that is in a React Hook.现在它在 React Hook 中。 I'm currently using useMethods , similar to useState .我目前正在使用useMethods ,类似于useState

The form I currently have is part of a multi-step process, and when I navigate to another page which the form is not on, it is unmounted (of course).我目前拥有的表单是一个多步骤过程的一部分,当我导航到另一个没有该表单的页面时,它会被卸载(当然)。 When re-mounted, I want to provide the form with initial values (available here ).重新安装时,我想为表单提供初始值(可在此处获得)。

The problem is that when my state changes the form re-renders and I always end up in an endless loop, because:问题是,当我的状态改变时,表单会重新渲染并且我总是以无限循环结束,因为:

  • The FormSpy stores changes in the form FormSpy存储表单中的更改
  • The state is changed状态变了
  • Form is re-rendered表单被重新渲染
  • The FormSpy stores changes in the form FormSpy存储表单中的更改
  • And so on...等等...

I also have a problem that when initial values are provided, the field state is not populated (dirty, touched, etc.), so the form looks strange when re-mounted because some of the labels are tied to the meta fields.我还有一个问题,当提供初始值时,字段状态未填充(脏、触摸等),因此重新安装时表单看起来很奇怪,因为某些标签与元字段相关联。 It seems like we need some kind of way to store all of the form state, not only the values as the component which contains the Form can unmount and re-mount n number of times.似乎我们需要某种方式来存储所有表单状态,而不仅仅是值,因为包含Form的组件可以卸载和重新安装n次。

What I want:我想要的是:

  • Changes to immediately to be stored in my state更改为立即存储在我的状态
  • Re-renders somehow remember (I can store this in my own state if needed) the touched, dirty, etc. state重新渲染以某种方式记住(如果需要,我可以将其存储在我自己的状态中)触摸、脏等状态

My starting point was to look at Auto-save with Debounce (although I don't need to debounce, since I'm storing it locally).我的出发点是查看使用去抖动自动保存(尽管我不需要去抖动,因为我将它存储在本地)。

What is the best way to handle this?处理这个问题的最佳方法是什么?

Always fascinated to discover a use case I'd never have considered.总是着迷于发现一个我从未考虑过的用例。 Since react-final-form@6.1.0 , you can now provide your own final-form form instance, via the form prop .react-final-form@6.1.0 ,您现在可以通过form prop提供您自己的final-form表单实例。 This, if stored at a higher place in the tree – with a useRef() , probably – might let you maintain form state for longer?这,如果存储在树中更高的位置——使用useRef() ,可能——会让你保持表单状态更长时间? 🤔 🤔

Just a guess.只是一个猜测。 Do report back if it works...如果有效,请回来报告......

I just had a similar issue, and manged to create a decorator that remembers the touched (or any other field state) and then re applies that state when the field is mounted again.我刚刚遇到了类似的问题,并设法创建了一个装饰器,该装饰器可以记住已触摸(或任何其他字段状态),然后在再次安装该字段时重新应用该状态。 One major issue is that this causes a flicker as the field is rendered not touched on mount, then the decorator is notified, then the field is rendered touched.一个主要问题是,这会导致闪烁,因为在装载时未触摸该字段,然后通知装饰器,然后渲染该字段。

Some example code (not tested):一些示例代码(未测试):

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});
}

You could also expose the storedTouched to allow setting any field touched, not just those that are already mounted/registered.您还可以公开storedTouched以允许设置任何触摸的字段,而不仅仅是那些已经安装/注册的字段。 (eg initialize it to the fields that were already touched last time) (例如将其初始化为上次已触及的字段)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM