我是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()
,然后多次读取我Probably Don't Need Derived State ...
所以我想知道这是否是正确的方法?
我的问题在此medium article中得到了很好的描述 我实施了解决方案(这也是React团队提出的)
但是感觉很hacky。 这是这样做的正确方法,还是我应该以不同的方式处理本地状态?想知道Dan Abramov如何处理这样的简单创建/更新应用程序=)
感谢您的帮助!
答案 0 :(得分:1)
您需要为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
组件提供的值来呈现适当的组件。