3

I'm getting this weird behavior that I don't know how to solve, on edit mode of this form if I refresh the page I get a bug where both the value and the placeholder are displayed in the field

-- This is my form component


const Form = () => {
  // fetch hook to get the settings data.
  const settings = useGetSettingsQuery();
  // initialize the useFormik hook with the data just fetched
  const form = useSettingsForm({ initialValues: settings.data?.data ?? {} });

  return (
    <Box>
      <Grid container spacing={2}>
         <Grid item xs={12}>
          <TextField
            fullWidth
            name={'id'}
            label={'id'}
            placeholder={'ticket id'}
            variant="outlined"
            value={form.values.id}
            onChange={form.handleChange}
          />
        </Grid>
        <Grid item xs={12}>
          initial values
          <pre>{JSON.stringify({ id: form.initialValues.id }, null, 2)}</pre>
        </Grid>
        <Grid item xs={12}>
          current value values
          <pre>{JSON.stringify({ id: form.values.id }, null, 2)}</pre>
        </Grid>
      </Grid>
    </Box>
  );
};

-- and this is my hook, right now I've deleted everything in my hook, and this is what's left:

export const useSettingsForm = ({ initialValues }: Props) => {
  return useFormik<Partial<ISetting>>({
    enableReinitialize: true,
    initialValues: {
      ...initialValues,
    },
    validationSchema: Yup.object().shape({}),
    onSubmit: async (values) => {
      console.log('submitted -> ', values);
    },
  });
};

the current behavior

enter image description here


For my useGetSettings hook, I'm using RTK query to fetch the data and handle the server state, this is the a snippet of apiSlice:

export const settingApiSlice = apiSlice.injectEndpoints({
  endpoints(builder) {
    return {
      getSettings: builder.query<IGetSettingsResp, void>({
        query() {
          return `/setting`;
        },
        providesTags: ['setting'],
      }),
    };
  },
});

export const { useGetSettingsQuery } = settingApiSlice;


as you can see in the picture the placeholder text and value are displayed, is there any way to fix this bug, thank you

Lazybob
  • 224
  • 3
  • 10
  • Can you show what `settings` is initially and perhaps output the `useGetSettingsQuery` hook contents? – Wesley LeMahieu Feb 15 '23 at 00:14
  • for the settings at first time it's empty (empty object) then when the data is fetched it gets reinitialized again with the new data, I've updated the question with more snippets. thank you @WesleyLeMahieu – Lazybob Feb 15 '23 at 00:40
  • Thank you. I apologize it was not necessary. I see the issue though is with the id. Check my revised answer. – Wesley LeMahieu Feb 15 '23 at 00:58
  • I apologize @WesleyLeMahieu, I've made a mistake in the pasting of the input to the question, in my code I'm using the name='id' as you suggested, and it's still the same issue. I also have this same issue with all of the other fields that I've on the same page I've updated the question with the right name – Lazybob Feb 15 '23 at 20:41

1 Answers1

0

In Formik, the name of the input ties into the property of it's value inside of form.values. So this:

<TextField
  fullWidth
  name={'ticket number'}
  label={'ticket number'}
  placeholder={'ticket number'}
  variant="outlined"
  value={form.values.id}
  onChange={form.handleChange}
/>

Should be this:

<TextField
  fullWidth
  name="id"
  label={'ticket number'}
  placeholder={'ticket number'}
  variant="outlined"
  value={form.values.id}
  onChange={form.handleChange}
/>

When you use name={'ticket number'} (or name="ticket number"), it's literally trying to set the value on form.values.ticket number instead of form.values.id, as you want it to be since that's your value.

The id in value={form.values.id} is connected to name="id".

Wesley LeMahieu
  • 2,296
  • 1
  • 12
  • 8