首页 文章

阿波罗形式国家管理

提问于
浏览
0

使用React Apollo客户端处理表单状态管理的最常规方法是什么?基本的apollo查询和简单的todo应用程序有太多的演练,但我没有看到如何处理真实的表单 .

想象三种不同的用户流程:

  • 编辑现有实体(更新表格)

  • 通过添加/删除元素来编辑集合(更新表单)

  • 创建新实体(创建表单)

似乎有一些解决方案:

  • 使用有状态的React组件 . 该有状态表单嵌套在 <Query /><Mutation /> 中,或以其他方式访问 datamutate . 在提交时,直接使用 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 回答

  • 0

    我发现 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 组件的渲染功能获得了大量的道具,这些道具都被描述为here . 您的实际表单组件可以是无状态的,并且基本上只渲染传递给它的道具(值,错误,onChange处理程序等) . Formik接受yup模式进行验证,这也使得验证输入也很容易 .

相关问题