#What's the recommended way to patch the entire form?
1 messages Β· Page 1 of 1 (latest)
So are you using the useForm hook? If so you could have a server component where you would fetch and see if there are values and in your client component you could take those values as prop and set it up in default values
I'm using plain React. Not NextJS, unfortunately, but that's a good idea.
you could also set the value like this ```const {
state: stateDemo,
store,
update,
reset,
setFieldValue,
} = useForm({
defaultValues: {
name: "first value",
},
});
useEffect(() => {
console.log("stateDemo", stateDemo);
const newValue = "test";
setFieldValue("name", newValue);
}, []);
@steady roost would this be the correct approach?
That's one way. It did cause some issues when I was moving the form field into a child component but it is one way. I was wondering if it was a way to patch the entire form instead of having to enter field by field.
yes, you could also change the entire form like this ``` const { state: stateDemo, store } = useForm({
defaultValues: {
name: "first value",
another: "another value",
},
});
useEffect(() => {
console.log("stateDemo", stateDemo);
store.setState((state) => {
return {
...state,
values: {
name: "hello world",
another: "another demo value",
},
};
});
}, []) ```
This should be stable
As in, it won't be likely to break in future releases for some time
@steady roost this doesn't seems to work for me. The form get the value, but the field does not reflect it. The same happened to me with the setFieldValue.
It does happen that my field is in a child componet if that may be important.
I have a minor preference towards StackBlitz, but either way π
Got it!
Uhm the problem is when the form is inside a conditional rendering like an if.
I will create the issue soon.
But here is the reproduction.
https://stackblitz.com/edit/stackblitz-starters-oj2quu?file=src%2FChild.tsx
The field's value set in the useEffect hook appears and suddenly disappears if we force the input element to rerender when field.state.value changes. Interesting
Ok, I think I made it work:
π https://stackblitz.com/edit/stackblitz-starters-gdmagd?file=src%2FApp.tsx
I simply replaced the useEffect hook in your example with these lines:
const fetchData = useCallback(async () => {
const p1 = new Promise<{ firstName: string }>((res) =>
setTimeout(() => res({ firstName: 'Isabelle' }), 3000)
);
const data = await p1;
form.setFieldValue('firstName', data.firstName);
}, [form]);
useEffect(() => {
fetchData();
}, [fetchData]);
Wdyt?
Lol, if I put setXData(data) into the body of the fetchData function, the issue remains appears again.
this kinda suggests to me that the issue is changing the state, maybe because that forces us to re-render the component, in which we run the (field) => <input .../> function
this is just intuition at this point
Let's test this hypothesis by profiling the two versions (modifying the state during data fetching vs not modifying):
1. Not modifying the state of <App /> during data fetching (first image)
1 rerender. Field changes bc one of its hooks. This must be because we changed its value when we called form.setFieldValue('firstName', data.firstName).
2. Modifying the state of <App /> during data fetching (second image)
3 commits.
*Commit 1: * (2nd image): The Field rerenders, bc one of its hooks has changed, I think this is when we update it through the api. I think this is the point when see the value we set in the Field.
Commit 2: (3rd and 4th image) <App /> rerenders, bc one of its hooks have changed. I think this is the setXData hook. This causes <Field/> to rerender too (4th image). This must be the point when our value disappears from the field and it starts with a blank state again.
Commit 3: (5th image) Nothing important happens. We can ignore it.
maybe if we change the default values of the form, it'll not instantiate the <Field /> with an empty value when it rerenders on the state change.
Yes, indeed. This is so much fun π€£
const [xData, setxData] = useState(null);
const form = useForm<{ firstName: string }>({
defaultValues: {
firstName: xData?.firstName,
},
onSubmit: async ({ value }) => {
console.log(value);
},
});
Well, I'm not familiar with the Form internals and have a PR in tanstack.com to finish, so I can't continue with this now, but maybe the info I found helps someone else to pick this up
Can we capture this in a ticket? π
Sure, I'll make one later today! βΊοΈ