T
TanStack2mo ago
stormy-gold

using useFieldContext with an Object

Hey, couldn't find any info on this, is this the correct/a possible way to work with objects? I know I could do name="object.property", however I probably want to be able to change multiple properties of the same object in 1 component This is my component:
import { useFieldContext } from "@/hooks/form";
import type { HeldTalent } from "@/schemas/held.schema";
import { TableCell, TableRow } from "./ui/table";
import { talentByName } from "@/lib/talente";
import { Input } from "./ui/input";

export default function TalentRow() {
const field = useFieldContext<HeldTalent>();
const talent = talentByName(field.state.value.talentName);

if(!talent) return;

return (
<TableRow>
<TableCell>{talent.name}</TableCell>
<TableCell>
<Input
type="number"
id={field.name}
value={field.state.value.TaW}
onChange={(e) => field.handleChange({...field.state.value, TaW: e.target.valueAsNumber})}
>
</Input>
</TableCell>
</TableRow>
)
}
import { useFieldContext } from "@/hooks/form";
import type { HeldTalent } from "@/schemas/held.schema";
import { TableCell, TableRow } from "./ui/table";
import { talentByName } from "@/lib/talente";
import { Input } from "./ui/input";

export default function TalentRow() {
const field = useFieldContext<HeldTalent>();
const talent = talentByName(field.state.value.talentName);

if(!talent) return;

return (
<TableRow>
<TableCell>{talent.name}</TableCell>
<TableCell>
<Input
type="number"
id={field.name}
value={field.state.value.TaW}
onChange={(e) => field.handleChange({...field.state.value, TaW: e.target.valueAsNumber})}
>
</Input>
</TableCell>
</TableRow>
)
}
And this is the Type definition:
export const HeldTalentSchema = z.object({
talentName: z.string(),
TaW: z.number().int(),
spEXP: z.number().int()
});
export type HeldTalent = z.infer<typeof HeldTalentSchema>;
export const HeldTalentSchema = z.object({
talentName: z.string(),
TaW: z.number().int(),
spEXP: z.number().int()
});
export type HeldTalent = z.infer<typeof HeldTalentSchema>;
1 Reply
fair-rose
fair-rose2mo ago
of course! Objects are allowed as field values, so contexts are also allowed. Just remember the React rule of immutable objects and you‘re good to go
- field.handleChange(prev => {
- prev.TaW = e.target.valueAsNumber;
- return prev
- })

+ field.handleChange(prev => ({...prev, TaW: e.target.valueAsNumber}))
- field.handleChange(prev => {
- prev.TaW = e.target.valueAsNumber;
- return prev
- })

+ field.handleChange(prev => ({...prev, TaW: e.target.valueAsNumber}))
note that compound fields lose information about specific fields. You can no longer tell the isTouched state apart from talentName and TaW for example Something worth checking is the error generation from the schema though … maybe it attempts mapping to object.property even though that field doesn‘t exist

Did you find this page helpful?