0

I don't know if this is a ReactAdmin question or a basic React one. If I should remove a tag (or add a different one) please let me know.

In a ReactAdmin application, I have an ArrayField nested inside a FormTab. In one of its components (DataGrid > FunctionField), I need access to the outer record available inside the FormTab and its ancestors. But the record property that was available there is now shadowed by a record property for the ArrayField.

The structure looks something like this:

const RulesEdit = ({record, options,...rest}) => {
  return (
    <Edit title={/*...*/} options={options} {...rest}>
      <TabbedForm>
        <!-- more -->
        <FormTab label="History" path="history">
          <ArrayField source="history" label="">
            <Datagrid>
              <!-- more -->
              <FunctionField label="Author" source="author_name" options={options} render={
                (record, ...args) => 
                   console.log({record, args, options}) ||  // *** Need parent information here ***
                   (<a href={`mailto:${record.author_email}`}>{record.author_name}</a>)
              }/>
              <!-- more -->
            </Datagrid>
          </ArrayField>
        </FormTab>
      </TabbedForm>
    </Edit>
  );
}

I thought that at worst, I could just pass a copy of the record from above down the component hierarchy, and I tried it like this:


export const RulesEdit = ({record, options,...rest}, rule=record) => {
  return (
    <Edit title={/*...*/} options={options} rule={rule} {...rest}>
      <TabbedForm rule={rule}>
        <!-- more -->
        <FormTab label="History" path="history" rule={rule} >
          <ArrayField source="history" label="" rule={rule}>
            <Datagrid rule={rule}>
              <!-- more -->
              <FunctionField label="Author" source="author_name" options={options} rule={rule} render={
                (record, ...args) => 
                   console.log({record, args, options, rule}) || // *** `rule` is an empty object here ***
                   (<a href={`mailto:${record.author_email}`}>{record.author_name})
              }/>
              <!-- more -->
            </Datagrid>
          </ArrayField>
        </FormTab>
      </TabbedForm>
    </Edit>
  );
}

But when I reach my component, the rule property is an empty object.

If I try it like this instead:


export const RulesEdit = ({record, options, ...rest}) => {
  const rule = record
  return (
    <Edit title={/*...*/} options={options} rule={record} {...rest}>
    <!-- ... -->
              <FunctionField label="Author" source="author_name" options={options} rule={rule} render={
                (record, ...args) => 
                   console.log({record, args, options, rule}) || // *** `rule` is undefined here ***
                   (<a href={`mailto:${record.author_email}`}>{record.author_name})
              }/>
    <!-- ... -->
  )
}

then I end up with rule being undefined.

I think I understand why that is, especially in the latter case. There must be some separation in time between the creation of this component and a later step when the data is applied to it. (This vague explanation shows my lack of React experience. I've done a number of small projects with no problem, but I don't know that I've ever really understood the core; any suggestions to help me improve this knowledge would also be valuable.)

The big problem is that I don't know how to get the additional parent data to this child when I need it available at render time. Any suggestions?

Scott Sauyet
  • 49,207
  • 4
  • 49
  • 103
  • Hi, maybe this will help you: FormDataConsumer -> formData - The whole form data / scopedFormData - The data for this item of the ArrayInput / getSource() - a function which will translate the source into a valid one for the ArrayInput: marmelab.com/react-admin/Inputs.html#linking-two-inputs – MaxAlex Apr 30 '20 at 02:39
  • @MaxAlex: thanks. I'll check it out. – Scott Sauyet Apr 30 '20 at 13:28
  • One thing I didn't mention is that this entire tab is static data. I don't need any complicated interactions with other fields, only a reference to parent as well as to the item from its child array that that I already have and which becomes the `record` for this `ArrayField`. It's to add a subject property to the mailto link above. That will include fields from this parent record. – Scott Sauyet Apr 30 '20 at 14:30
  • @MaxAlex: Thank you very much for the lead. Using `FormDataConsumer` worked fine for my case. – Scott Sauyet May 01 '20 at 20:01

0 Answers0