首页 > 解决方案 > GraphQL 使用 React 创建或更新表单的最佳模式?

问题描述

我是 GraphQL 新手,但有 React 经验。

我正在尝试使用 React 和 Apollo 构建一个简单的应用程序,其中使用相同的表单来创建或更新实体,比如Post

我不想复制表单,所以我想我会定义一个PostForm组件并从两个CreatePostPage页面UpdatePostPage使用。

CreatePostPage.js(简化)

const CreatePostPage = ({match}) => (
  <div>
    <h1>Create Post</h1>
    <Mutation mutation={POST_CREATE}>
      {(createPost, {data}) => (
        <PostForm onSubmit={(formData) => createPost(formData)} />
      )}
    </Mutation>
  </div>
)

UpdatePostPage.js(简化版)

const UpdatePostPage = ({match}) => (
  <div>
    <h1>Update Post</h1>
    <Query query={POST_GET} variables={{id: match.params.id}}>
      {({ data, networkStatus }) => {
        const post = data && data.post ? omitDeep(data.post, '__typename') : null;
        return (
          <Mutation mutation={POST_UPDATE}>
            {(updatePost, {data}) => (
              <PostForm post={post} onSubmit={(formData) => updatePost(formData)} />
            ))}
          </Mutation>
        );
      }}
    </Query>
  </div>
  )

现在PostForm需要维护自己的状态,以便用户可以编辑帖子。我打算使用componentWillReceiveProps(),看到现在这样做的方法是getDerivedStateFromProps(),然后多次阅读我可能不需要派生状态......

所以我想知道这是否是正确的方法?

我的问题在这篇中型文章中得到了很好的描述, 我实现了解决方案(这也是由 React 团队提出的)

但感觉很hacky。这是正确的方法还是我应该以不同的方式处理当地状态?想知道 Dan​​ Abramov 如何处理这样一个简单的创建/更新应用程序 =)

感谢您的帮助!

标签: reactjsstateapolloreact-apollo

解决方案


您将需要一个有状态的组件PostForm,但据我所知,您不需要使用componentWillReceivePropsgetDerivedStateFromProps。在这种特殊情况下,您的post道具只是用来初始化您的状态。你应该做的是阻止你的组件渲染,直到你真正拥有发布数据。

你可以这样做:

<Query query={POST_GET} variables={{id: match.params.id}}>
  {({ data, networkStatus }) => {
    if (!data.post) return null; // data itself should never be undefined
    const post = omitDeep(data.post, '__typename');
    return (
      <Mutation mutation={POST_UPDATE}>
        {(updatePost, {data}) => (
          <PostForm post={post} onSubmit={(formData) => updatePost(formData)} />
        ))}
      </Mutation>
    );
  }}
</Query>

然后在 PostForm 的构造函数中,您可以将初始状态设置为props.post.

当然,您可能需要考虑加载和错误状态,在这种情况下,您应该根据组件提供的值呈现适当的Query组件。


推荐阅读