fjurr
fjurr

Reputation: 552

React - onSubmit form without any data

I put a submit test button but its not getting any data.

OBS about the code:

  1. I'm using react select
  2. I'm using filepond to upload images and files (its working fine)
  3. ProductsModal is a modal component with rightColumn and leftColumn (left column is the form and right column there is a phone image with dynamic content inside which is a preview of the form.

My onSubmit function is a console.log with data from the form, but all I get is a empty object.

I have the following code

import React, { useState } from 'react'
import useForm from 'react-hook-form'
import Select from 'react-select'
import { FaRegFileAlt, FaRegImage } from 'react-icons/fa'
import { FilePond, registerPlugin } from 'react-filepond'
import { IoIosImages } from 'react-icons/io'
import FilePondPluginImageExifOrientation from 'filepond-plugin-image-exif-orientation'
import FilePondPluginImagePreview from 'filepond-plugin-image-preview'
import TextField from '@material-ui/core/TextField'
import Button from '~/components/Button'
import ProductsModal from '~/components/Sponsor/Modals/ProductsModal'
import IconsProductImage from '~/components/Sponsor/IconsProductImage'
import Border from '~/components/Border'
import ProductBadge from '~/components/ProductBadge'
import * as S from './styled'

registerPlugin(FilePondPluginImageExifOrientation, FilePondPluginImagePreview)

export default function ModalAnnouncement({ handleCloseModal, showModal }) {
  const [title, setTitle] = useState('')
  const [tags, setTags] = useState([])
  const [about, setAbout] = useState('')
  const [files, setFiles] = useState('')
  const [filePreview, setFilePreview] = useState('')
  const [images, setImages] = useState('')

  const [updatingFile, setUpdatingFile] = useState(false)
  const [updatingImage, setUpdatingImage] = useState(false)

  const { handleSubmit, setValue } = useForm()

  function onSubmit(data) {
    console.log('data', data)
  }

  function handleUpdatingFile() {
    setUpdatingFile(!updatingFile)
  }

  function handleUpdatingImage() {
    setUpdatingImage(!updatingImage)
  }

  function handleUpdateImages(event) {
    setImages(event)
    setFilePreview(event.length === 0 ? '' : URL.createObjectURL(event[0].file))
  }

  function handleTagsChange(tags) {
    setValue('tags', tags)
    setTags(tags)
  }

  const tagsAvailable = [
    { value: 1, label: 'artificial intelligence' },
    { value: 2, label: 'digital marketing' },
    { value: 3, label: 'big data' },
    { value: 4, label: 'blogging' },
    { value: 5, label: 'chatbot' },
    { value: 6, label: 'content marketing' },
    { value: 7, label: 'digital loyalty' },
    { value: 8, label: 'digital transformation' },
    { value: 9, label: 'email marketing' },
    { value: 10, label: 'engagement' },
  ]

  const reactSelectStyleCustom = {
    control: (base, state) => ({
      ...base,
      boxShadow: state.isFocused ? 0 : 0,
      borderColor: state.isFocused ? '#50A5D2' : base.borderColor,
      borderWidth: state.isFocused ? '1px' : '1px',
      '&:hover': {
        borderColor: state.isFocused ? '#50A5D2' : base.borderColor,
      },
    }),
    placeholder: defaultStyles => {
      return {
        ...defaultStyles,
        color: '#A1A1A1',
        fontSize: '16px',
      }
    },
    singleValue: provided => {
      const overflow = 'visible'
      const fontStyle = 'normal'
      const transition = 'opacity 300ms'

      return { ...provided, overflow, fontStyle, transition }
    },
  }

  return (
    <ProductsModal
      modalTitle="New Announcement"
      handleCloseModal={handleCloseModal}
      showModal={showModal}
      leftColumn={
        <form onSubmit={handleSubmit(onSubmit)}>
          <S.FormContainer>
            <S.InputTitle>Title</S.InputTitle>
            <TextField
              fullWidth={true}
              variant="outlined"
              name="title"
              placeholder="Give your announcement a title"
              type="text"
              value={title}
              onChange={e => setTitle(e.target.value)}
            />
            <div className="mt-3">
              <S.InputTitle>About</S.InputTitle>
              <TextField
                fullWidth={true}
                variant="outlined"
                name="about"
                multiline
                rows="4"
                placeholder="Tell them a little more about your announcement"
                type="text"
                value={about}
                onChange={e => setAbout(e.target.value)}
              />
            </div>
            <div className="mt-3">
              <S.InputTitle>Tags</S.InputTitle>
              <Select
                styles={reactSelectStyleCustom}
                isMulti
                options={tagsAvailable}
                placeholder="Add tags to your announcement"
                value={tags}
                onChange={handleTagsChange}
              />
            </div>
            <div className="mt-4 mb-2">
              <Border />
            </div>
            {updatingFile ? (
              <div className="mt-2">
                <div className="d-flex justify-content-center align-items-center">
                  <FaRegFileAlt className="mr-2" size={14} />{' '}
                  <S.InputTitle>Files</S.InputTitle>
                </div>
                <FilePond
                  allowMultiple={false}
                  files={files}
                  onupdatefiles={setFiles}
                />
              </div>
            ) : (
                <div className="d-flex justify-content-center">
                  <Button
                    text="Add file"
                    type="button"
                    color="#5A6978"
                    action={handleUpdatingFile}
                    width="160px"
                    height="40px"
                  />
                </div>
              )}

            {updatingImage ? (
              <div className="mt-3">
                <div className="d-flex justify-content-center align-items-center">
                  <FaRegImage className="mr-2" size={14} />{' '}
                  <S.InputTitle>Images</S.InputTitle>
                </div>
                <FilePond
                  allowMultiple={false}
                  files={images}
                  onupdatefiles={handleUpdateImages}
                />
              </div>
            ) : (
                <div className="d-flex justify-content-center">
                  <Button
                    text="Add image"
                    type="button"
                    color="#5A6978"
                    action={handleUpdatingImage}
                    width="160px"
                    height="40px"
                  />
                </div>
              )}
            <div className="d-flex justify-content-center">
              <Button
                text="Submit Form"
                type="submit"
                color="#5A6978"
                action={(event) => { event.persist(); handleSubmit(event) }}
                width="160px"
                height="40px"
              />
            </div>
          </S.FormContainer>
        </form>
      }
      rightColumn={
        <>
          <S.Phone>
            <S.Screen>
              <S.Content>
                <div className="image-container">
                  {filePreview !== '' ? (
                    <>
                      <img className="animated fadeIn" src={filePreview} />
                      <IconsProductImage right="0" top="30%" />
                      <div className="ml-2 mt-3">
                        <S.ProductTitle>{title}</S.ProductTitle>
                      </div>
                      <div
                        style={{ marginTop: '-10px' }}
                        className="d-flex ml-2"
                      >
                        <ProductBadge
                          text="annoucement"
                          color="#D40707"
                          textColor="#FFF"
                          width="135px"
                          height="30px"
                          eventText="- engagement"
                          eventTextColor="#87919A"
                        />
                      </div>
                    </>
                  ) : (
                      <>
                        <img
                          style={{
                            postison: 'relative',
                            backgroundColor: '#CCC',
                          }}
                          className="d-flex justify-content-center align-items"
                        />
                        <IoIosImages
                          style={{
                            position: 'absolute',
                            top: '125px',
                            right: '125px',
                          }}
                          color="red"
                          size={28}
                        />
                        <div className="ml-2 mt-3">
                          <S.ProductTitle>
                            {title === '' ? (
                              'Title'
                            ) : (
                                <S.ProductTitle>{title}</S.ProductTitle>
                              )}
                          </S.ProductTitle>
                        </div>
                        <div
                          style={{ marginTop: '-10px' }}
                          className="d-flex ml-2"
                        >
                          <ProductBadge
                            text="annoucement"
                            color="#D40707"
                            textColor="#FFF"
                            width="135px"
                            height="30px"
                            eventText="- engagement"
                            eventTextColor="#87919A"
                          />
                        </div>
                        <S.AboutSection>
                          <span>{about}</span>
                        </S.AboutSection>
                      </>
                    )}
                </div>
              </S.Content>
            </S.Screen>
            <S.Home />
          </S.Phone>
        </>
      }
    />
  )

Upvotes: 0

Views: 217

Answers (1)

Leander
Leander

Reputation: 148

react-hook-form is not built to be used with controlled input elements.

Your input elements have an onChange handler attached to them which is effectively making your form a controlled one. If this is intended, you should pull the setValue method out of useForm and manually update the value to be used with react-hook-form.

See the bottom of this page to read more about using react-hook-form with controlled elements. React Hook Form FAQ

Upvotes: 2

Related Questions