使用React Apollo客户端处理表单状态管理的最常规方法是什么?基本的阿波罗查询和简单的待办事项应用程序的演练太多了,但是我没有看到过展示如何处理现实形式的演练。
想象三个不同的用户流:
似乎有一些解决方案:
使用有状态的React组件。该状态形式嵌套在<Query />
和<Mutation />
中,或者可以同时访问data
和mutate
。提交后,直接使用mutate
函数提交突变,并在成功时(如有必要)手动更新缓存。它可以工作,但是需要更复杂的有状态组件。副作用之一是您必须从props(componentWillReceiveProps
等)计算状态,因为表单需要同时使用query
(用于更新表单以显示当前值)和{{1} },并且可能会在表单呈现后(通过refetch / poll)接收新数据
使用Apollo-Link-State和mutation
范围的查询。这似乎与有状态组件一样面临所有相同的问题,即使不是更多,因为有更多的间接访问。创建表单/新实体很直观,因为新实体可以保存在本地缓存中,然后在提交时发送到远程API,并在成功时自动出现在普通缓存中。但是,对于更新表单而言,它不那么直观,因为现在您基本上拥有同一对象的两个副本。表单还必须切换其真相来源,以最初从普通缓存中读取以填充表单,然后在编辑期间写入本地缓存/从本地缓存中读取,然后在提交后可能恢复为普通缓存。否则,诸如https://www.robinwieruch.de/react-apollo-link-state-tutorial/之类的很好的解释将不会显示如何发送本地缓存的数据,并且通常只关注仅用于本地的数据,例如设备API结果和用户配置。
在访问api的数据上方写入权威/“普通”阿波罗缓存,然后从缓存中读取回去,以将其提交给远程API。对于更新表单,这似乎更有意义,因为该实体只有一个状态,但是对于该新实体将不起作用,因为该实体还没有ID(尽管我们可以在客户端上生成uuid,我更愿意允许后端生成ID),因此AFALO缓存不能与AFAIK一起使用。与此相关的另一个问题是,用户刚提交的表单数据在获取时将被覆盖,如果某些操作不可行,这可能会令人沮丧。
感谢任何建议,示例或意见-预先感谢!
答案 0 :(得分:1)
我发现apollo-link-state
在您要管理完全属于客户端而不是要从服务器获取的数据的一部分的状态时更为有用。我认为它不太适合管理组件状态,尤其是表单。最好的方法是将Apollo与Formik之类的库结合使用。这减少了样板,降低了组件的整体复杂性。这是一个粗略的示例:
<Query query={SOME_QUERY} />
{({ loading, data }) => {
if (loading) return <LoadingIndicator/>
return (
<Mutation query={SOME_MUTATION}>
{(mutate) => (
<Formik
initialValues={_.pick(data.someData, ['foo', 'bar'])}
validate={/** optional validation function or schema **/}
onSubmit={values => mutate({ variables: values })}
>
{(formikProps) => (
<YourFormComponent {...formikProps}/>
)}
</Formik>
)}
</Mutation>
)
}}
</Query>
Formik
组件的render函数获得大量道具,所有道具都here中进行了描述。您的实际表单组件可以是无状态的,并且基本上只是呈现传递给它的道具(值,错误,onChange处理程序等)。 Formik接受yup模式进行验证,这也使验证输入变得很容易。