我是 GraphQL 的新手,但有 React 的经验。
我正在尝试使用 React 和 Apollo 构建一个简单的应用程序,其中使用相同的表单来创建或更新实体,例如帖子。
我不想复制表单,所以我想我会定义一个PostForm
组件并从CreatePostPage
和UpdatePostPage
页面使用。
创建帖子页面.js(简化(
const CreatePostPage = ({match}) => (
<div>
<h1>Create Post</h1>
<Mutation mutation={POST_CREATE}>
{(createPost, {data}) => (
<PostForm onSubmit={(formData) => createPost(formData)} />
)}
</Mutation>
</div>
)
更新后页.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 团队提出的(
但感觉很笨拙。 这是执行此操作的正确方法还是我应该以不同的方式处理本地状态?想知道丹·阿布拉莫夫将如何处理像这样的简单创建/更新应用程序 =(
感谢您的帮助!
您的PostForm
需要一个有状态的组件,但据我所知,您无需使用componentWillReceiveProps
或getDerivedStateFromProps
。在这种特殊情况下,您的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
组件提供的值来呈现相应的组件。