Search code examples
reactjsreduxantdredux-sagareact-forms

Unable to use react form data in useEffect hook


I have an antd form where I am able to get the form data in onFinish function upon hitting submit button in which I wanted to use uesEffect hook and dispatch an action with form data as payload to redux saga but I got following error

React Hook "useEffect" is called in function "onFinish" that is neither a React function component nor a custom React Hook function.

If I write useEffect hook outside the onFinsh function, I am unable to get the form data/values


Please suggest a workaround to get the form data values outside of onFinish function


import React, { useState, useEffect } from 'react';
import ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import './index.css';
import { Form, Input, Button, Checkbox } from 'antd';
 

const Demo = () => {
  const onFinish = (values) => {
    // alert(JSON.stringify(values['username']));
    useEffect(() => {
      // dispatch an action with values as payload
     }, []);
  };
console.log(values) // UNABLE TO GET VALUES HERE...HOW TO GET IT???
  return (
    <Form
      name="basic"
      onFinish={onFinish}>
      <Form.Item
        label="Username"
        name="username">
        <Input />
      </Form.Item>
      <Form.Item>
        <Button type="primary" htmlType="submit">
          Submit
        </Button>
      </Form.Item>
    </Form>
  );
};

ReactDOM.render(<Demo />, document.getElementById('container'));

Solution

  • It looks like you don't even need the useEffect() hook. Just dispatch the action from within the onFinish() and have state store the values

    const Demo = () => {
    
      const [ values, setValues ] = useState([]);
      
      const onFinish = (recievedValues) => {
        // dispatch here
        setValues(recievedValues);
      }
      
      console.log(values) // <-- you can get it here
      return (<div> ... </div>);
    };

    Or better yet, since you are already saving the values in redux during dispatch, you should use that in your render code as well:

    import { useSelector } from 'react-redux';
    
    const Demo = () => {
    
      //point to the state where your data is
      const stateValues = useSelector(state => state.your.data);
      
      const onFinish = (recievedValues) => {
        // dispatch here
      }
      
      console.log(stateValues) // <-- you can get it here
      return (<div> ... </div>);
    };