handling state with react context and react hook form

Viewed 31

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
0 Answers
Related