<FormDataConsumer>
Edition forms often contain linked inputs, e.g. country and city (the choices of the latter depending on the value of the former).
The <FormDataConsumer> component gets the current (edited) values of the record and passes it to a child function.
As <FormDataConsumer> uses the render props pattern, you can avoid creating an intermediate component like the <CityInput> component above:
import * as React from 'react';import { Edit, SimpleForm, SelectInput, FormDataConsumer } from 'react-admin';
const countries = ['USA', 'UK', 'France'];const cities: Record<string, string[]> = { USA: ['New York', 'Los Angeles', 'Chicago', 'Houston', 'Phoenix'], UK: ['London', 'Birmingham', 'Glasgow', 'Liverpool', 'Bristol'], France: ['Paris', 'Marseille', 'Lyon', 'Toulouse', 'Nice'],};const toChoices = (items: string[]) => items.map(item => ({ id: item, name: item }));
const OrderEdit = () => ( <Edit> <SimpleForm> <SelectInput source="country" choices={toChoices(countries)} /> <FormDataConsumer<{ country: string }>> {({ formData, ...rest }) => ( <SelectInput source="cities" choices={ formData.country ? toChoices(cities[formData.country]) : [] } {...rest} /> )} </FormDataConsumer> </SimpleForm> </Edit>);Hiding Inputs Based On Other Inputs
Section titled “Hiding Inputs Based On Other Inputs”You may want to display or hide inputs based on the value of another input - for instance, show an email input only if the hasEmail boolean input has been ticked to true.
For such cases, you can use the approach described above, using the <FormDataConsumer> component.
import { FormDataConsumer } from 'react-admin';
const PostEdit = () => ( <Edit> <SimpleForm shouldUnregister> <BooleanInput source="hasEmail" /> <FormDataConsumer<{ hasEmail: boolean }>> {({ formData, ...rest }) => formData.hasEmail && <TextInput source="email" {...rest} /> } </FormDataConsumer> </SimpleForm> </Edit>);Usage inside an ArrayInput
Section titled “Usage inside an ArrayInput”When used inside an <ArrayInput>, <FormDataConsumer> provides one additional property to its child function called scopedFormData. It’s an object containing the current values of the currently rendered item. This allows you to create dependencies between inputs inside a <SimpleFormIterator>, as in the following example:
import { FormDataConsumer } from 'react-admin';
const PostEdit = () => ( <Edit> <SimpleForm> <ArrayInput source="authors"> <SimpleFormIterator> <TextInput source="name" /> <FormDataConsumer<{ name: string }>> {({ formData, // The whole form data scopedFormData, // The data for this item of the ArrayInput ...rest }) => scopedFormData && scopedFormData.name ? ( <SelectInput source="role" // Will translate to "authors[0].role" choices={[ { id: 1, name: 'Head Writer' }, { id: 2, name: 'Co-Writer' }, ]} {...rest} /> ) : null } </FormDataConsumer> </SimpleFormIterator> </ArrayInput> </SimpleForm> </Edit>);| Prop | Required | Type | Default | Description |
|---|---|---|---|---|
children | Required | function | - | A function that takes the formData and returns a ReactNode |
children
Section titled “children”The function used to render a component based on the formData.
<FormDataConsumer<{ name: string }>> {({ formData, // The whole form data scopedFormData, // The data for this item of the ArrayInput }) => { /* ... */ }}</FormDataConsumer>