3

I would like to display a Tab inside the TabbedShowLayout only if the record has a specific property. I tried to create a custom component as below:

const EventsTab = ({...props, record}) => {
  return record && record.hasEvents &&
  <Tab label="Tab2">
    test
  </Tab>
}

and then add it inside the Show layout as:

<Show {...props}>
  <TabbedShowLayout>
    <Tab label="Tab1">
      <MetricsComp {...props} />
    </Tab>
    <EventsTab {...props}/>
  </TabbedShowLayout>
</Show>

but I get the following error: uncaught at finalize Invariant Violation: EventsTab(...): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.

Admin-on-rest allows conditional rendering of a component (like in How to access record's internals in Show/Edit/Create) but not a Tab. Is there any workaround?

Michail Michailidis
  • 11,792
  • 6
  • 63
  • 106
giokokos
  • 602
  • 1
  • 6
  • 20

2 Answers2

3

We had to do something similar - Unfortunately we don't have access of record in Show but we have in TabbedShowLayout. So we decided to create a custom TabbbedShowLayout with render() of TabbedShowLayout changed like that:

render() {
    const {
        children,
        contentContainerStyle,
        record,
        resource,
        basePath,
        translate,
        version,
    } = this.props;
    let changedChildren = children;

    if (record.excludeTab) {
        changedChildren = [];

        for (let i=0; i<children.length; i++) {
            if (children[i] instanceof Array) {
                changedChildren.push(children[i]);
            } else if (children[i] instanceof Object 
                       && children[i].props.label !== "TabToExcludeLabel") {
                changedChildren.push(children[i]);
            }
        }

    }
    return (
        <div style={divStyle} key={version}>
            <Tabs
                value={this.state.value}
                onChange={this.handleChange}
                contentContainerStyle={contentContainerStyle}
            >
                {React.Children.map(
                    changedChildren,
                    (tab, index) => ....
    )
 }
Michail Michailidis
  • 11,792
  • 6
  • 63
  • 106
1

I am not sure and I may be being presumptuous but you component EventsTab will basically return a boolean and not a valid react component. Is the below what you are looking for?

const EventsTab = ({...props, record}) => {
  return record ? record.hasEvents ?
  (<Tab label="Tab2">
    test
  </Tab>): null: null
}
kunal pareek
  • 1,285
  • 10
  • 21
  • this resolves the problem of the error thrown but it creates a Tab with no title! this should be because of problematic behavior of TabbedShowLayout – Michail Michailidis Mar 16 '18 at 12:24