0

I am using a React library called Kendo React in order to create a simple form. What I want is to be able to submit my form when the data is changed by clicking on the Load new user button, however the current behavior is that when I click the button and populate with data the submit button does not submit form until I manually change the value of the field, why and how can I just submit the form immediately after I update the data and the button is enabled? Here is my code:

import React from 'react';
import ReactDOM from 'react-dom';
import { Form, Field, FormElement } from '@progress/kendo-react-form';
import { Error } from '@progress/kendo-react-labels';
import { Input } from '@progress/kendo-react-inputs';
const emailRegex = new RegExp(/\S+@\S+\.\S+/);

const emailValidator = value => emailRegex.test(value) ? "" : "Please enter a valid email.";

const EmailInput = fieldRenderProps => {
  const {
    validationMessage,
    visited,
    ...others
  } = fieldRenderProps;
  return <div>
        <Input {...others} />
        {visited && validationMessage && <Error>{validationMessage}</Error>}
      </div>;
};

const App = () => {
  const handleSubmit = dataItem => alert(JSON.stringify(dataItem, null, 2));

  const [user, setUser] = React.useState({
    firstName: 'John',
    lastName: 'Smith',
    email: 'John.Smith@email.com'
  });

  const loadNewUser = () => {
    setUser({
      firstName: 'NewFirstName',
      lastName: 'NewLastName',
      email: 'NewEmails@email.com'
    });
  };

  return <React.Fragment>
        <button className='k-button' onClick={loadNewUser}> Load new user </button>
        <hr className='k-hr' />
        <Form onSubmit={handleSubmit} initialValues={user} key={JSON.stringify(user)} render={formRenderProps => <FormElement style={{
      maxWidth: 650
    }}>
              <fieldset className={'k-form-fieldset'}>
                <legend className={'k-form-legend'}>Please fill in the fields:</legend>
                <div className="mb-3">
                  <Field name={'firstName'} component={Input} label={'First name'} />
                </div>

                <div className="mb-3">
                  <Field name={'lastName'} component={Input} label={'Last name'} />
                </div>

                <div className="mb-3">
                  <Field name={"email"} type={"email"} component={EmailInput} label={"Email"} validator={emailValidator} />
                </div>
              </fieldset>
              <div className="k-form-buttons">
                <button type={'submit'} className="k-button" disabled={!formRenderProps.allowSubmit}>
                  Submit
                </button>
              </div>
            </FormElement>} />
      </React.Fragment>;
};

ReactDOM.render(<App />, document.querySelector('my-app'));
Phat Baba
  • 53
  • 7

1 Answers1

0

this is normal because when you use setUser a render event is triggered and not a change event on your inputs, so to submit your form on every loadNewUser click, you can add the submit logic to loadNewUser method after setUser. The last option is better as you avoid triggering the submit logic before setUser call inside loadNewUser.

Or use UseEffect to perform the submit on each change to the user object.

  useEffect(() => {
      console.log(user);
  }, [user]);

Here is a simple example ( without Kendo ) :

import { useEffect, useState } from "react";

export default function App() {
  const [user, setUser] = useState(null);

  const loadNewUser = () => {
    setUser({ name: "alan" });
  };
  const onchange = (event) => {
    setUser({
      ...user,
      name: event.target.value
    });
  };
  const submit = () => {
    console.log("submit", user);
  };
  useEffect(() => {
    user && submit();
  }, [user]);

  return (
    <div className="App">
      <button onClick={loadNewUser}>Load new user</button>
      <input
        type="text"
        onChange={onchange}
        value={user != null ? user.name : ""}
      />
      <button onClick={submit}>submit</button>
    </div>
  );
}
Zouhair Dre
  • 558
  • 4
  • 14