GithubHelp home page GithubHelp logo

Comments (7)

Hudsxn avatar Hudsxn commented on April 28, 2024 1

The reason you'll get an infinite loop on this is you're subscribing to onSubmit, inside onSubmit you're calling e.preventDefault(), which stops the default behavior. then asking it to resubmit, which fires the exact event again, causing it to recursively execute into a stack overflow error.

This isn't a bug with react, more a simple error. What you may want to do is have a conditional in place that can stop the endless recursion. I don't know what checks you want to perform, but here's an example.

const isReadyToSend = (args:any)  : boolean => {
     // do something.
}

export const handleFormWithRecaptcha = (action: string) => {
    return (e: React.FormEvent<HTMLFormElement>) => {
        if (!isReadyToSend()) {
              e.preventDefault();
             // Some stuff
             e.target.submit()
        }
    }
}

This way, you can check if the submit request needs to be intercepted, and if it needs to be intercepted, resend (if that's the desired behavior).

from react.

yousefelgoharyx avatar yousefelgoharyx commented on April 28, 2024 1

Hmm it's 2am and i'm not really concentrated but at least the suggestion react gives leads to an infinite loop, that's really bad
also there no where in the docs where they mention how to submit programatically

from react.

Eyuelb avatar Eyuelb commented on April 28, 2024 1

@Hudsxn Thanks Formatting the code.I don't think this Issue is on react so it needs to be closed

from react.

Hudsxn avatar Hudsxn commented on April 28, 2024

This isn't a react issue. You also have the right call in terms of submission. You are calling an infinite loop by your design. Also, there isn't any documentation on how to submit a form because this is standard DOM functionality, you're correct by calling e.target.submit() you simply need to re-assess your onSubmit listener and stop it from running recursively. As mentioned in my prior comment, you simply need to add a conditional to break this loop.

from react.

Eyuelb avatar Eyuelb commented on April 28, 2024

hi @yousefelgoharyx i used a Custome Form Component for this I created a custom component that accepts the validation as Form component props with the target field TFieldValues[] as type. each time the error is fulfilled it needs to check if the second validation is true

    className,
    children,
    onSubmitHandler,
    validOn,
    id 
  }: FormComponent<TFieldValues>): React.ReactNode => {
    const formId = Array.isArray(validOn) ? validOn.join(",") : validOn;

    const handleFormSubmit = (data: TFieldValues) => {
      console.log("Custom submit function");
      onSubmit(data);
      onSubmitHandler && onSubmitHandler(data);
    };
    const onError = (
      errors?: FieldErrors<TFieldValues> | undefined,
) => {
      if (errors ) {
        const isValid =
          validOn &&
          (Array.isArray(validOn)
            ? validOn.every(
                (field) =>
                  methods.getValues(field) && errors[field] === undefined
              )
            : methods.getValues(validOn) && errors[validOn] === undefined);

        if (isValid) {
          if (onSubmitHandler) {
            Array.isArray(validOn)
              ? onSubmitHandler(methods.watch())
              : onSubmitHandler(methods.getValues(validOn));
          }
        }
        else{
          console.log({ errors, isValid });

        }
      }
    };
    return (
      <form
        id={id}
        noValidate
        onSubmit={methods.handleSubmit(handleFormSubmit, onError
        )}
        className={className}
      >
        {children}
        <input type="submit" id={id} ref={submitButtonRef} hidden />
        {/* <DevTool control={methods.control} /> */}
      </form>
    );
  };

from react.

Hudsxn avatar Hudsxn commented on April 28, 2024

Hi @Eyuelb your code hasn't formatted correctly in markdown, to make it easier to read for OP I've formatted it, and broken it into seperate parts to make it a little easier to understand. I think maybe OP doesn't understand how the DOM events work. @yousefelgoharyx I've attached a diagram on this comment explaining where you're going wrong.

import React from 'react';

// Define the props for the Form component
interface FormComponent {
  className?: string;
  children?: React.ReactNode|React.ReactNode[];
  onSubmitHandler?: (data: TFieldValues) => void;
  validOn?: string | string[];
  id?: string;
}

const methods:Record<string,CallableFunction> = {}; 

// Assuming TFieldValues and FieldErrors are defined elsewhere in your code
type TFieldValues = any;
type FieldErrors<T> = Record<string, T>;

// Define the Form component with comments
const Form = ({
  className,
  children,
  onSubmitHandler,
  validOn,
  id
}: FormComponent): React.ReactNode => {
  // Convert validOn to a string if it's an array, otherwise use it directly
  const formId = Array.isArray(validOn) ? validOn.join(",") : validOn;

  // Handle form submission
  const handleFormSubmit = (data: TFieldValues) => {
    console.log("Custom submit function");
    onSubmitHandler && onSubmitHandler(data);
  };

  // Handle form errors
  const onError = (errors?: FieldErrors<TFieldValues> | undefined) => {
    if (errors) {
      // Check validity based on validOn
      const isValid =
        validOn &&
        (Array.isArray(validOn)
          ? validOn.every(
              (field) =>
                methods.getValues(field) && errors[field] === undefined
            )
          : methods.getValues(validOn) && errors[validOn] === undefined);

      if (isValid) {
        // Call onSubmitHandler with the form data if it exists
        if (onSubmitHandler) {
          Array.isArray(validOn)
            ? onSubmitHandler(methods.watch())
            : onSubmitHandler(methods.getValues(validOn));
        }
      } else {
        console.log({ errors, isValid });
      }
    }
  };

  // Render the form with its children
  return (
    <form
      id={id}
      noValidate
      onSubmit={methods.handleSubmit(handleFormSubmit, onError)}
      className={className}
    >
      {children}
      {/* Hidden submit button to trigger form submission */}
      <input type="submit" id={id} ref={submitButtonRef} hidden />
      {/* Uncomment the line below to include the DevTool component */}
      {/* <DevTool control={methods.control} /> */}
    </form>
  );
};

export default Form;

@yousefelgoharyx - I've got a inkling you're not fully clued about how events work in DOM. None of this is an issue with React, this needs to be marked as closed. You could do the same with any UI framework, i.e VueJS, svelt, you would still have the same issue because this is down to how you're handling the event.

What you're doing in your code is:
1.Listening for the submit event
2.Preventing the default action
3.Executing some code
4.Re-submitting the submit event, causing this to go back to step 1

Screenshot from 2024-02-03 14 05 18
When instead you should be doing this:
Screenshot from 2024-02-03 14 10 50

from react.

yousefelgoharyx avatar yousefelgoharyx commented on April 28, 2024

OH MY GOD
How did I not see this
that's really embarrassing. I guess I've spent too much time submitting forms with axios in event handlers xD
Thank you all

from react.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.