Search code examples
reactjsreduxsemantic-ui-react

Get form values in semantic-ui-react


Here is my form:

import React from 'react'
import { Form, Button } from 'semantic-ui-react'

const CreatePostForm = ({ onSubmit }) =>
  <Form onSubmit={onSubmit}>
    <Form.Input name='user' label='user' placeholder='Enter user name' />
    <Form.Input name='title' label='title' placeholder='Enter post title' />
    <Form.Input name='text' label='text' placeholder='Enter post text' />
    <Form.Input name='category' label='category' placeholder='Enter post category' />
    <Button type='submit'>Submit</Button>
  </Form>

export default CreatePostForm

It is then connected:

import { connect } from 'react-redux'
import CreatePostForm from '../components/CreatePostForm.jsx'

const mapDispatchToProps = (dispatch, props) => {
  return {
    onSubmit: (e, data) => {
      console.log(e)
      console.log(data)
    },  
  }
} 

const ConnectedCreatePostForm = connect(null, mapDispatchToProps)(CreatePostForm)
export default ConnectedCreatePostForm

In onSubmit I expect some data to be passed that would allow me to retrieve each input form field value by name but I can't access it somehow: there is event and data (I would hope for) which is just the form itself not really data. How to access the values upon submission? I don't want to handle state and want my component - CreatePostForm - to stay dumb.


Solution

  • You can use FormData to get the data from the inputs for the form directly:

    Object.fromEntries(new FormData(event.target))
    

    will give you an object made from the data of the form. (Note Object.fromEntries is a somewhat newer API. There's a lodash method: fromPairs that is functionally identical if needed)

    Edit: If you need to use lodash's fromPairs: you'll need to do as follows, as lodash's fromPairs doesn't automatically go over the FormData as an iterator:

    fromPairs(Array.from(new FormData(target)))
    

    You could also grab the values directly from the form element by the input name:

    console.log(event.target.user.value);
    

    This will allow you to be able to use the form without having to set it up as controlled components.

    Example below. I didn't include Semantic in the example because this is vanilla JS.

    const CreatePostForm = () =>{
      const onSubmit = (event)=>{
        event.preventDefault();
        const {target} = event;
        console.log('FormData', Object.fromEntries(new FormData(target)));
        console.log('target.user.value', target.user.value);
      }
      return <form onSubmit={onSubmit}>
        <input name='user' label='user' placeholder='Enter user name' />
        <input name='title' label='title' placeholder='Enter post title' />
        <input name='text' label='text' placeholder='Enter post text' />
        <input name='category' label='category' placeholder='Enter post category' />
        <button type='submit'>Submit</button>
      </form>
    }
    
    ReactDOM.render(<CreatePostForm />, document.getElementById('root'));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
    <div id="root"/>