Search code examples
javascriptreactjsstyled-componentsformik

How to pass a styled component instead of string message to formik's thanks response


My formik contact form returns a "thanks" string under the form after it is successfully submitted, and I want it to return a styled component instead so it can be styled.

This successfully returns string "thanks" message, though it is unstyled:

const ContactForm = () => {
    const classes = useStyles()

    const [serverState, setServerState] = useState()
    const handleServerResponse = (ok, msg) => {
        setServerState({ ok, msg })
    }

    const handleOnSubmit = (values, actions) => {
        axios({
            method: "POST",
            url: "https://formspree.io/user-id",
            data: values
        })
            .then(response => {
                actions.setSubmitting(false)
                actions.resetForm()
                handleServerResponse(true, "Thanks!") //returns unstyled string at the bottom of the page
            })
            .catch(error => {
                console.log(error)
                actions.setSubmitting(false);
                handleServerResponse(false, error.response.data.error);
            })
    }

This returns nothing at all:

const ContactForm = () => {
    const classes = useStyles()

    const [serverState, setServerState] = useState()
    const handleServerResponse = (ok, msg) => {
        setServerState({ ok, msg })
    }

    const handleOnSubmit = (values, actions) => {
        axios({
            method: "POST",
            url: "https://formspree.io/user-id",
            data: values
        })
            .then(response => {
                actions.setSubmitting(false)
                actions.resetForm()
                handleServerResponse(true, () => { 
                    return (
                        <Thanks>Thanks!</Thanks>  // styled component I'd like to return
                    )
                }
              )
            })
            .catch(error => {
                console.log(error)
                actions.setSubmitting(false);
                handleServerResponse(false, error.response.data.error);
            })
    }

How can I successfully reference my own component here? here's a codesandbox I put together


Solution

  • I'd do something like this:

    const ContactForm = () => {
        const classes = useStyles()
    
        const [serverState, setServerState] = useState()
        const handleServerResponse = (ok, msg) => {
            setServerState({ ok, msg })
        }
    
        const handleOnSubmit = (values, actions) => {
            axios({
                method: "POST",
                url: "https://formspree.io/user-id",
                data: values
            })
                .then(response => {
                    actions.setSubmitting(false)
                    actions.resetForm()
                    handleServerResponse(true, "Thanks!") //returns unstyled string at the bottom of the page
                })
                .catch(error => {
                    console.log(error)
                    actions.setSubmitting(false);
                    handleServerResponse(false, error.response.data.error);
                })
        }
    
        if (serverState && serverState.ok && serverState.msg) return <Thanks>{ serverState.msg }</Thanks>;
    
    
    

    If you need to show the form or whatever as well, then include the conditional within your existing return :).

    e.g.

      return (
         <Fragment>
             <form>
                 ...
             </form>
             { serverState && serverState.ok && serverState.msg && (
                  <Thanks>{ serverState.msg }</Thanks>
             )}
         </Fragment>
      );