javascriptreactjsreact-hookscloudinary

React child component removes parent state after callback


I have a form where one can upload an image using the Cloudinary image upload widget.

The widget is wrapped inside an ImageUpload component:

<Form.Group controlId="image">
   <Form.Label>Cover Image:</Form.Label>
   <ImageUpload
      curUrl={form.image}
      imageUrl={(url) => {
      console.log("Adding image");

      setField("image", url);
      }}
   />
  <p
     className={`custom-error-message ${
     !!errors.imageErr ? "show" : "hide"
    }`}>
     {errors.imageErr}
   </p>
</Form.Group>

Notice the imageUrl callback function.

When the child component calls imageUrl with the uploaded URL, the state of the whole form gets deleted, except for the image URL itself.

I'm using setField to update the form state:

const setField = (
  field: keyof IFormErrors,
  value: string | number | Date | boolean
) => {
  setForm({
    ...form,
    [field]: value,
  });
  // Check and see if errors exist, and remove them from the error object:
  if (!!errors[field])
    setErrors({
      ...errors,
      [field]: null,

I don't think the error is in the setField function because other input fields that use this function do not remove the form state.

I am wondering where the error can be.

I have no idea how this error originates as the child component should not be able to remove the parent's state with just a callback.

Can it be an error with the widget e.g., 3rd party?

Or am I missing a fundamental understanding of React state and the binding of parent-child components?


Solution

  • This is a suggestion given the amount of info that you have provided, so might not be a solution to your problem, but should still help you to find the root cause nonetheless.

    First of all, I do not see any major concern in your code.

    If the setForm is a React.useState, you can check the value by doing

    setForm((prevFormValue) => {
      console.log(prefFormValue)
      return {
        ...prevFormValue,
        [field]: value,
    }
    

    This is helpful because this will help make sure that the existing form value is still there by console logging it out. If not, you might have a bigger problem.

    You'd also need to make sure both setForm and setField are in the same scope of the ImageUpload component so all values/functions are readily available to use.

    If non of the above helps, more context to your code would be appreciated to do further debug.

    Cheers.