Actions

A form without form actions like submit, save, send or in the context of a wizard, next and prev, would be kind of pointless. As actions are rendered inside the Form render prop, you can place them whererever you like, in whatever way you like.

Actions inside the render prop could look something like this:

<Form
    ...
    render={({ actionProps, fieldProps }) => (
        <>
            {/* ... rendering of fields ... */}
            <button
                type="button"
                onClick={() => actionProps.handleActionClick(payload => console.log("onSubmit:", payload), true)}
            >
                Submit
            </button>
        </>
    )}
/>

As you see, you get a group of properties with the actionProps prop. These are:

  • handleActionClick: This one expects a callback which will receive the forms data and if the second argument is set to true, it will only be executed if the form is valid. An additional optional third parameter (boolean) let's you reset the form back to the initial data.
  • isDisabled: This will be true if the form is disabled, so you can disable actions, as well
  • isDirty: If you only want to save data when it has changed, than you can use this boolean to find that out

Stages comes with an example component to render actions. You can use it as a starter for your own implemntation. This is the source code:

const Actions = ({ config, handleActionClick, isDisabled }) => (
    <>
        {config.map((action, index) =>{
            if (action.type === "primary") {
                return (
                    <button
                        type="button"
                        onClick={() => handleActionClick(action.onClick, action.validate)}
                        key={`action-${index}`}
                        disabled={isDisabled}
                    >
                        <strong>{action.title}</strong>
                    </button>
                );
            }
            return (
                <button
                    type="button"
                    onClick={() => handleActionClick(action.onClick, action.validate)}
                    key={`action-${index}`}
                    disabled={isDisabled}
                >
                    {action.title}
                </button>
            );
        })}
    </>
);

The config would look something like this:

[
    {
        title: "Cancel",
        type: "secondary",
        validate: false,
        onClick: () => window.location.href = "/"
    },
    {
        title: "Submit",
        type: "primary",
        validate: true,
        onClick: data => onSubmit(data)
    }
]

Especially in the context of a wizard, it's a good idea to abstract the actions this way as they can be very dynamic.