Monday, June 3, 2024
 Popular · Latest · Hot · Upcoming
108
rated 0 times [  110] [ 2]  / answers: 1 / hits: 42676  / 5 Years ago, sat, june 15, 2019, 12:00:00

GitHub discussion about this issue - https://github.com/jaredpalmer/formik/issues/529




I passed formik values to a function that is called in <Field/>'s onChange but when I type in the <Field/>, the last character does not fall into the function.



CodeSandbox - link



Screenshot:



enter



Minimal Code Instance:



import React from react;
import ReactDOM from react-dom;
import { Formik, Form, Field, FieldArray } from formik;

function App() {
//------ HERE ----------
const getValues = values => console.log(values.fields[0]);
//----------------------
return (
<>
<Formik
initialValues={{ fields: [] }}
onSubmit={(values, actions) => {
actions.setSubmitting(false);
console.log(values);
return false;
}}
render={({ setFieldValue, values }) => (
<Form>
<FieldArray
name=fields
render={() => (
<Field
type=text
name=fields.0
placeholder=Write something
onChange={e => {
setFieldValue(fields.0, e.target.value);
//---------------
getValues(values);
//---------------
}}
/>
)}
/>
</Form>
)}
/>
</>
);
}

ReactDOM.render(<App />, document.getElementById(root));

More From » html

 Answers
13

I am not familiar with formik and I just took a quick look on the implementation.
But here's my two cents on the issue.



Why are the values not updating after each call?



You are trying to get the values before the rerendering is happening and the value you have is the old one always, because the component is not updated yet.



To verify try to add console.log(values.fields[0]); in the App component before the getValue definition.



Why is the call happening before the rerendering?



The onChange implementation will trigger the handleChange in which it's a memoized function call that will not be triggered if you have the same value BUT you changed the value.



handleChange will be triggered if the executeChange value is different and executeChange also memoized that depends on setFieldValue or the state.values.



setFieldValue is an event callback that only update the ref after each render. That's from formik docs // we copy a ref to the callback scoped to the current state/props on each render and that didn't happen yet in your case -useEventCallback-.



Once the state is updated by the action then your component will be updated but your function is not called yet.



setFieldValue will try to validate the input and return a promise and bubble that up to executeChange and handleChange and it treats that as a low priority so it's not a blocking call.



A quick solution might be is to use onKeyUp instead of onChange I think that will bypass the useCallback and actually updates the component with higher priority call



function App({ values, setFieldValue }) {
console.log(Rerendering,values.fields[0])
//------ HERE ----------
const getValues = () => console.log(values.fields[0]);
//----------------------

return (
<div className=formik-wrapper>
<Form>
<FieldArray
name=fields
render={() => (
<Field
type=text
name=fields.0
placeholder=Write something
onKeyUp={e => {
setFieldValue(fields.0, e.target.value);
getValues();
}}
/>
)}
/>
</Form>
</div>
);
}


I hope this can help or at least lead for some help.



Check formik implementation


[#51996] Sunday, June 9, 2019, 5 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
anikas

Total Points: 258
Total Questions: 102
Total Answers: 95

Location: Monaco
Member since Sun, Jan 16, 2022
2 Years ago
anikas questions
;