Formik: Formik + Next.js (SSR in general?) in production build

Created on 25 Apr 2019  路  5Comments  路  Source: formium/formik

馃悰 Bug report

Unable to use Formik + Next.js in production build. Development build works just fine but the production one gives me an error.

This is minimal code to reproduce. I have also prepared full Formik + Next.js setup here https://github.com/dlitsman/formik-nextjs-bug

import React from 'react';
import {Formik, Field} from 'formik';

const CreateForm = () => {
  return (
    <Formik
      initialValues={{
        test: '13',
      }}
      onSubmit={() => {}}
      render={(props) => (
        <form onSubmit={props.handleSubmit}>
          <Field name="test" />
        </form>
      )}
    />
  );
}

export default CreateForm;

Current Behavior

It throws this error

TypeError: Cannot read property 'values' of undefined
    at t.render (/Users/dmitry/projects/tmp/next-formik-bug/node_modules/formik/dist/formik.cjs.production.js:1:11336)
    at c (/Users/dmitry/projects/tmp/next-formik-bug/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:35:231)
    at Sa (/Users/dmitry/projects/tmp/next-formik-bug/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:36:1)
    at a.render (/Users/dmitry/projects/tmp/next-formik-bug/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:41:467)
    at a.read (/Users/dmitry/projects/tmp/next-formik-bug/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:41:58)
    at renderToString (/Users/dmitry/projects/tmp/next-formik-bug/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:53:83)
    at render (/Users/dmitry/projects/tmp/next-formik-bug/node_modules/next-server/dist/server/render.js:86:16)
    at renderPage (/Users/dmitry/projects/tmp/next-formik-bug/node_modules/next-server/dist/server/render.js:211:20)
    at Function.value (/Users/dmitry/projects/tmp/next-formik-bug/.next/server/static/UbGu0lVv6x2Nd4p3fdJFP/pages/_document.js:8

Expected behavior

Production and development builds work the same way.

Reproducible example

https://github.com/dlitsman/formik-nextjs-bug

Your environment

| Software | Version(s) |
| ---------------- | ---------- |
| Formik |1.5.2
| React |16.8.6
| TypeScript |-
| Browser |-
| npm/Yarn |npm
| Operating System |MacOS 10.14.4

Most helpful comment

One hack: create a separate component with formik and load with dynamic import
https://nextjs.org/docs#with-no-ssr

import dynamic from 'next/dynamic'

const MyForm = dynamic(
  () => import('/path/to/form'),
  {
    ssr: false
  }
)

const MyComponent = () => (
  <div>
    <h1>My Form</h1>
    <MyForm />
  </div>
)

All 5 comments

Since Next.js renders universally, existing react components may not be compatible completely. This seems to be especially true for the Field component in Formik. Until SSR support is added (not sure if it is already added), this is a viable temporary fix. The lifecycle hooks were needed to reset the the state with Field import made. Hope this helps! 馃憤

This is done because componentDidMount will always run on the client

import React from 'react';
import * as FormikAll from 'formik';

class CreateForm extends React.Component{
  constructor(props) {
    super();  // super(props) if you need to access this.props in here
    this.state = {
      Field: null
    }
  }

  componentDidMount() {
      let { Field } = FormikAll; 
      this.setState({
        Field
      });
  }

  render() {
    const { Formik } = FormikAll;
    const Field = this.state.Field;

    let FieldContent = Field ? 
    (
      <Field name="test" />
    ) : true

    return (
      <Formik
        initialValues={{
          test: '13',
        }}
        onSubmit={() => {}}
        render={(props) => (
          <form onSubmit={props.handleSubmit}>
            {FieldContent}
          </form>
        )}
      />
    );
  }
}

export default CreateForm;

@whitetig3r Thanks for the example snippet! It works, but only on the client side...

However, it does not explain why the original example works in development mode. npm run dev works fine for me without any hacks. Sounds like it has something to do with minimized version... Any ideas?

Also, it seems v2.0.1-alpha.2 works just fine without any hacks in production mode as well. Hope it will be released soon 馃

@dlitsman You're right! Seems to be a problem with the minified formik.cjs.production.js file where the formik property on this.props is undefined in some places. The v2.0.1-alpha.2 seems to work well in production! Hope to see a release soon, too! 馃

One hack: create a separate component with formik and load with dynamic import
https://nextjs.org/docs#with-no-ssr

import dynamic from 'next/dynamic'

const MyForm = dynamic(
  () => import('/path/to/form'),
  {
    ssr: false
  }
)

const MyComponent = () => (
  <div>
    <h1>My Form</h1>
    <MyForm />
  </div>
)

@whitetig3r Do you refer to the release candidate 2? Can't find any alpha versions at all :)
https://www.npmjs.com/package/formik/v/2.0.1-rc.2

Tried out both that and the latest rc.10, but instead gets a TypeError: Cannot read property 'touched' of undefined.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

giulioambrogi picture giulioambrogi  路  3Comments

jaredpalmer picture jaredpalmer  路  3Comments

pmonty picture pmonty  路  3Comments

najisawas picture najisawas  路  3Comments

sibelius picture sibelius  路  3Comments