Cannot read property 'values' of undefined
TypeError: Cannot read property 'values' of undefined
at Effect.webpackJsonp../node_modules/formik-effect/dist/formik-effect.es6.js.Effect.componentWillReceiveProps (node_modules/formik-effect/dist/formik-effect.es6.js:38:0)
at callComponentWillReceiveProps (node_modules/react-dom/cjs/react-dom.development.js:11527:0)
at updateClassInstance (node_modules/react-dom/cjs/react-dom.development.js:11719:0)
at updateClassComponent (node_modules/react-dom/cjs/react-dom.development.js:13153:0)
at beginWork (node_modules/react-dom/cjs/react-dom.development.js:13824:0)
at performUnitOfWork (node_modules/react-dom/cjs/react-dom.development.js:15863:0)
at workLoop (node_modules/react-dom/cjs/react-dom.development.js:15902:0)
at renderRoot (node_modules/react-dom/cjs/react-dom.development.js:15942:0)
at performWorkOnRoot (node_modules/react-dom/cjs/react-dom.development.js:16560:0)
at performWork (node_modules/react-dom/cjs/react-dom.development.js:16482:0)
Not to throw an error :)
Codesandbox link pls
@Andreyco https://codesandbox.io/s/1863qll037
Formik is using new Provider/Consumer from react 16.3, while formik-effect library still relies on old context api.
I am using withFormik hoc, so I was able to do something like this with lodash and componentWillReceiveProps:
componentWillReceiveProps(nextProps) {
if (!isEmpty(nextProps.values) && !isEqual(this.props, nextProps)) {
// values have changed
}
}
formik-effect does almost the same thing internally:
https://github.com/jaredpalmer/formik-effect/blob/master/src/formik-effect.tsx
@jaredpalmer any work around on this? either fixing formik-effect or something else..
import * as React from "react";
import { FormikProps, FormikState, connect } from "formik";
export interface IEffectProps<TValues = {}> {
onChange(
currentState: FormikState<TValues>,
prevState: FormikState<TValues>
): void;
formik: FormikProps<TValues>;
}
const Effect = class FormikEffect<TValues = {}> extends React.Component<IEffectProps<TValues>, {}> {
componentDidUpdate(prevProps: IEffectProps<TValues>) {
const { values, touched, errors, isSubmitting, isValidating } = this.props.formik;
const {
values: prevValues,
touched: prevTouched,
errors: prevErrors,
isSubmitting: prevIsSubmitting,
isValidating: prevIsValidating
} = prevProps.formik;
if (prevProps.formik !== this.props.formik) {
this.props.onChange({
values,
touched,
errors,
isSubmitting,
isValidating
} as FormikState<TValues>,
{
values: prevValues,
touched: prevTouched,
errors: prevErrors,
isSubmitting: prevIsSubmitting,
isValidating: prevIsValidating
} as FormikState<TValues>
);
}
}
render() {
return null;
}
}
export default connect(Effect);
Uses formik prop induced by connect instead directly accessing context. Also note that it uses the componentDidUpdate lifecycle function instead of componentWillReceiveProps.
Hola! So here's the deal, between open source and my day job and life and what not, I have a lot to manage, so I use a GitHub bot to automate a few things here and there. This particular GitHub bot is going to mark this as stale because it has not had recent activity for a while. It will be closed if no further activity occurs in a few days. Do not take this personally--seriously--this is a completely automated action. If this is a mistake, just make a comment, DM me, send a carrier pidgeon, or a smoke signal.
ProBot automatically closed this due to inactivity. Holler if this is a mistake, and we'll re-open it.
I believe this hasn't been fixed, it just happened to me with the last versions of Formik (1.3.2) & FormikEffect (1.2.0).
I'm using the following (derived mostly from @FabianSellmann above):
import * as React from 'react';
import { connect } from 'formik';
class FormikEffect extends React.Component {
componentDidUpdate(prevProps) {
if (prevProps.formik !== this.props.formik) {
this.props.onChange(this.props.formik, prevProps.formik);
}
}
render() {
return null;
}
}
export default connect(FormikEffect);
Calling it as:
<FormikEffect onChange={(current, prev) => {
if (current.values.someKey !== prev.values.someKey) {
console.info('someKey changed to', current.values.someKey);
}
}} />
I'm using the following (derived mostly from @FabianSellmann above):
import * as React from 'react'; import { connect } from 'formik'; class FormikEffect extends React.Component { componentDidUpdate(prevProps) { if (prevProps.formik !== this.props.formik) { this.props.onChange(this.props.formik, prevProps.formik); } } render() { return null; } } export default connect(FormikEffect);Calling it as:
<FormikEffect onChange={(current, prev) => { if (current.values.someKey !== prev.values.someKey) { console.info('someKey changed to', current.values.someKey); } }} />
This helped me thanks
@dlerman2's above example produces an error in React 16.3.0:
Warning: Cannot update a component from inside the function body of a different component.
This is from a change in React stating, "A React component should not cause side effects in other components during rendering." The workaround is to call the handler in a useEffect hook.
This solution works for me:
import { connect } from 'formik';
import { useEffect, useState, useRef } from 'react';
function usePrevious(value) {
const ref = useRef();
useEffect(() => {
ref.current = value;
});
return ref.current;
}
function FormikEffect({ onChange, formik: { values } }) {
const [firstRender, setFirstRender] = useState(true);
const previousValues = usePrevious(values);
useEffect(() => {
if (firstRender) {
setFirstRender(false);
} else {
onChange(previousValues, values);
}
}, [onChange, values]);
return null;
}
export default connect(FormikEffect);
Most helpful comment
I'm using the following (derived mostly from @FabianSellmann above):
Calling it as: