I have a form that has an add/edit mode. In edit mode, my text area input takes the post.content as the default value. When I edit the post once, it's working, the post is edited but When I edit the post a second time, the default value of the text area is the old state post.content and not the edited one. Do you know why the value of the text area not taking the last post state? If I refresh before two edits there is no problem
PostsContext.tsx
const reducer = (state: PostsState, action: PostsAction) => {
switch (action.type) {
case 'SET_POSTS':
return { posts: action.payload }
case 'ADD_POST':
return { posts: [action.payload, ...state.posts] }
case 'UPDATE_POST':
return {
posts: state.posts.map((post) => {
if (post.id === action.payload.id) {
return action.payload
}
return post
}),
}
case 'DELETE_POST':
return {
posts: state.posts.filter((post) => post.id !== action.payload.id),
}
default:
return state
}
}
Posts.tsx
const Posts = ({ post }: Props) => {
const { dispatch } = usePostsContext()
const { dispatch } = usePostsContext()
const {
register,
handleSubmit,
control,
watch,
reset,
formState: { isSubmitting, errors },
} = useForm<FormInput>({
defaultValues: {
content: post?.content || '',
},
resolver: yupResolver(postSchema),
})
const onSubmit: SubmitHandler<FormInput> = async (data) => {
const formData = new FormData()
formData.append('content', data.content)
data.thumbnailFile && formData.append('thumbnailFile', data.thumbnailFile[0])
const response = await fetch(
`${import.meta.env.VITE_API_URL}/api/posts/${post ? post.id : ''}`,
{
method: post ? 'PATCH' : 'POST',
credentials: 'include',
body: formData,
}
)
const json = await response.json()
if (response.ok) {
dispatch({ type: post ? 'UPDATE_POST' : 'ADD_POST', payload: json })
reset()
post && setUpdateMode(false)
}
}
return (
<Avatar />
{!updateMode && (
<div className="dropdown dropdown-end">
<label tabIndex={0} className="btn btn-square">
...
</label>
<ul
tabIndex={0}
className="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-52"
>
<li>
<span onClick={() => setUpdateMode(true)}>Edit</span>
</li>
<li>
<span onClick={handleDelete}>Delete</span>
</li>
</ul>
</div>
)}
</div>
{updateMode ? (
<form onSubmit={handleSubmit(onSubmit)}>
<div className="flex flex-col">
<textarea
className="w-full h-32 p-2 border border-gray-300 rounded-lg"
placeholder="What's on your mind?"
{...register('content', { required: true })}
/>
</div>
)}
<div className="divider"></div>
{post ? (
<div className="flex items-center">
<button
className="btn btn-outline btn-ghost mr-2"
onClick={() => {
reset(), setUpdateMode(false)
}}
>
Cancel
</button>
<button type="submit" className="btn btn-accent" disabled={isSubmitting}>
{isSubmitting ? 'Saving...' : 'Save'}
</button>
</div>
) : (
<button type="submit" className="btn btn-accent" disabled={isSubmitting}>
{isSubmitting ? 'Posting...' : 'Post'}
</button>
)}
</div>
</form>
) : (
post && (
<Post />
)
)
}
export default Posts