使用React Apollo客户端处理表单状态管理的最常规方法是什么?基本的apollo查询和简单的todo应用程序有太多的演练,但我没有看到如何处理真实的表单 .
想象三种不同的用户流程:
-
编辑现有实体(更新表格)
-
通过添加/删除元素来编辑集合(更新表单)
-
创建新实体(创建表单)
似乎有一些解决方案:
-
使用有状态的React组件 . 该有状态表单嵌套在
<Query />
和<Mutation />
中,或以其他方式访问data
和mutate
. 在提交时,直接使用mutate
函数提交变异,并且(如果需要)在成功时手动更新缓存 . 它有效,但需要更复杂的有状态组件 . 其中一个副作用是你必须从道具(componentWillReceiveProps
等)计算状态,因为表单需要query
(用于更新表单,显示当前值)和mutation
,并且可能在表单之后接收新数据已经渲染(在refetch / poll上) -
使用Apollo-Link-State和
@client
- 范围查询 . 这似乎面临着与有状态组件相同的所有问题,如果不是因为额外的间接性 . 对于创建表单/新实体来说,它是直观的,因为新实体可以保存在本地缓存中,然后在提交时发送到远程API,并在成功时自动出现在正常缓存中 . 但是,对于更新表单来说,它不太直观,因为现在您基本上有两个相同对象的副本 . 表单还必须切换其真实来源,最初从普通缓存中读取以填充表单,然后在编辑期间写入/读取本地缓存,然后可能在提交后恢复到正常缓存 . 否则,像https://www.robinwieruch.de/react-apollo-link-state-tutorial/ don 't show how to send in that locally-cached data, and generally focus on data that'这样的好解释只能保持本地化,例如设备API结果和用户配置 . -
写入权威/'正常'的apollo缓存,在api-fetched数据上,然后从缓存中读回它以将其提交给远程API . 这似乎对更新表单更有意义,因为该实体只有一个状态,但不适用于新实体,因为该实体还没有id(虽然我们可以在客户端生成uuid,我宁愿允许后端生成id)因此不是Apollo缓存可以使用的东西,AFAIK . 另一个问题是用户刚刚提交的表单数据将在fetch上被覆盖,如果某些东西不起作用,这可能会令人沮丧 .
感谢任何建议,示例或输入 - 提前感谢!
1 回答
我发现
apollo-link-state
对于想要管理从服务器获取的状态的情况更有用 . 我不太适合管理组件状态,尤其是表单 . 最好的方法是将Apollo与像Formik这样的图书馆结合起来 . 这减少了样板和整体复杂性以及组件 . 这是一个粗略的例子:Formik
组件的渲染功能获得了大量的道具,这些道具都被描述为here . 您的实际表单组件可以是无状态的,并且基本上只渲染传递给它的道具(值,错误,onChange处理程序等) . Formik接受yup模式进行验证,这也使得验证输入也很容易 .