GraphQL 使用 React 创建或更新表单的最佳模式?
Best pattern for GraphQL create or update form with 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
需要维护自己的状态,以便用户可以编辑 post。
我打算使用 componentWillReceiveProps()
,看到现在这样做的方法是 getDerivedStateFromProps()
,然后多次阅读我 Probably Don't Need Derived State...
所以我想知道这样做是否正确?
我的问题在 medium article 中得到了很好的描述
我实现了解决方案(也是React团队提出的)
但感觉很hacky。
这是执行此操作的正确方法还是我应该以不同方式处理本地状态?想知道 Dan Abramov 如何处理像这样的简单 create/update 应用 =)
感谢您的帮助!
您的 PostForm
需要一个有状态组件,但据我所知,您不需要使用 componentWillReceiveProps
或 getDerivedStateFromProps
。在这种特殊情况下,您的 post
道具只是用来初始化您的状态。你应该做的是阻止你的组件呈现,直到你真正拥有 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
组件提供的值来呈现适当的组件。
我是 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
需要维护自己的状态,以便用户可以编辑 post。
我打算使用 componentWillReceiveProps()
,看到现在这样做的方法是 getDerivedStateFromProps()
,然后多次阅读我 Probably Don't Need Derived State...
所以我想知道这样做是否正确?
我的问题在 medium article 中得到了很好的描述 我实现了解决方案(也是React团队提出的)
但感觉很hacky。 这是执行此操作的正确方法还是我应该以不同方式处理本地状态?想知道 Dan Abramov 如何处理像这样的简单 create/update 应用 =)
感谢您的帮助!
您的 PostForm
需要一个有状态组件,但据我所知,您不需要使用 componentWillReceiveProps
或 getDerivedStateFromProps
。在这种特殊情况下,您的 post
道具只是用来初始化您的状态。你应该做的是阻止你的组件呈现,直到你真正拥有 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
组件提供的值来呈现适当的组件。