How to pass props to component inside Field react final form

597 views Asked by At

I have a form created with react-final-form, inside i have a field that use a functional component to manage an image file.

I have the component inside the father component, but i think that is not a good practice and sonarLint show me a warning.

I put the component outside of the father component, but i need to pass some props, if not the component not works.

Inside my i can not achive to pass the props, i don't find in the documentation in react-final-form, how to do it.

Could you help me?

my field in the form:

<div className="col-md-1 mb-4">
                  <label htmlFor="image" className="form-label text-center" >
                    <h5> Imagen </h5>
                  </label>
                </div>
                <div className="col-md-5">
                  <Field
                    name="image"
                    type="file"
                    component={UploadImage} //this is the component that need props
                    onKeyDown={(e) => { e.key === 'Enter' && e.preventDefault(); }} 
                  />
                </div>

Component outside the father component: (if works i would like to create a helper, because this component is being used in three other forms)

function UploadImage({setImageUpdate, image, imageUpdate}) {
  const onDrop = useCallback((file) => { 
    console.log('file', file);     
   /*  input.onChange(file);
    console.log(input.onChange(file)); */
    getImages()
      .then(imagesFolder => {          
        if (imagesFolder.includes(file[0].name)) {
          confirm({
            title: "Reemplazar Imagen",
            content: `La imagen ${file[0].name} ya existe en la base de datos. Quieres cambiarla igualmente?`,
            okText: "Sustituir",
            okType: "danger",
            cancelText: "Cancelar",
            onOk() {
              setImageUpdate(file);
            }
          });
        } else {
          setImageUpdate(file);
        }
      })
      .catch(error => console.log(error));
  }, []);

  const { getRootProps, getInputProps } = useDropzone({
    accept: "image/jpeg",
    noKeyboard: true,
    onDrop,
  });

  function handleRemoveClick (imageUpdate){     
    confirm({
      title: "Borrar Imagen",
      content: `Seguro que quieres eliminar la imagen ${imageUpdate}?`,
      okText: "Borrar",
      okType: "danger",
      cancelText: "Cancelar",
      onOk() {         
        setImageUpdate([]);
      }
    });
  }

  return (
    <div>
      {imageUpdate.length === 0 || imageUpdate[0] === "" ? (
        <div {...getRootProps()}>
          <input {...getInputProps()} />
          <div className="btn btn-outline-primary" >Click or Drag to Upload</div>
        </div>
      ) : (
        <>
          {imageUpdate[0].name || image} <div className="btn btn-outline-danger ms-4" onClick={() => handleRemoveClick(image)}><i className="bi bi-trash"></i> </div>
        </>

      )}
    </div>
  );
}
1

There are 1 answers

0
ddaudiosolutions On

Ok i have a solution:

<div className="col-md-1 mb-4">
                  <label htmlFor="image" className="form-label text-center" >
                    <h5> Imagen </h5>
                  </label>
                </div>
                <div className="col-md-5">
                  <Field
                    name="image"
                    type="file"
                    component={UploadImage} //this is the component that need props
                     props = {{                      
                      imageUpdate: imageUpdate,
                      setImageUpdate: setImageUpdate,
                    }}  
                    onKeyDown={(e) => { e.key === 'Enter' && e.preventDefault(); }} 
                  />
                </div>

you can pass props inside the Field, and then inside the functional component you can handle this props like you want.

function UploadImage({props, input}) {
  const onDrop = useCallback((file) => { 
    console.log('file', file);     
    input.onChange(file);    
    getImages()
      .then(imagesFolder => {          
        if (imagesFolder.includes(file[0].name)) {
          confirm({
            title: "Reemplazar Imagen",
            content: `La imagen ${file[0].name} ya existe en la base de datos. Quieres cambiarla igualmente?`,
            okText: "Sustituir",
            okType: "danger",
            cancelText: "Cancelar",
            onOk() {
              setImageUpdate(file);
            }
          });
        } else {
          setImageUpdate(file);
        }
      })
      .catch(error => console.log(error));
  }, []);

  const { getRootProps, getInputProps } = useDropzone({
    accept: "image/jpeg",
    noKeyboard: true,
    onDrop,
  });

  function handleRemoveClick (imageUpdate){     
    confirm({
      title: "Borrar Imagen",
      content: `Seguro que quieres eliminar la imagen ${imageUpdate}?`,
      okText: "Borrar",
      okType: "danger",
      cancelText: "Cancelar",
      onOk() {         
        setImageUpdate([]);
      }
    });
  }

  return (
    <div>
      {imageUpdate.length === 0 || imageUpdate[0] === "" ? (
        <div {...getRootProps()}>
          <input {...getInputProps()} />
          <div className="btn btn-outline-primary" >Click or Drag to Upload</div>
        </div>
      ) : (
        <>
          {imageUpdate[0].name || image} <div className="btn btn-outline-danger ms-4" onClick={() => handleRemoveClick(image)}><i className="bi bi-trash"></i> </div>
        </>

      )}
    </div>
  );
}