RelayJS: child components requesting arbitrary data

I am creating a panel containing many different widgets. The user can add and remove any widgets and place them in any order in which they prefer. Each widget has its own data requirements. What is the correct relay method for creating a container hierarchy?

To provide some context, this architecture is still:

Widget is a component that receives a configuration object and displays the corresponding component accordingly.

class Widget extends React.Component {
  render() {
    const {widget} = this.props;
    // widgetMap is a map that maps string to React component
    const ActualWidget = widgetMap.get(widget.component);

    return (
      <ActualWidget data={widget.data} />
    );
  }
}

export default Relay.createContainer(Widget, {
  fragments: {
    data: () => Relay.QL`
      fragment on ??? {
        # What should be here since we don't know what will be rendered?
      }
    `
  }
});

Dashboard The component contains several widgets added by the user.

class Dashboard extends React.Component {
  renderWidgets = () => {
    return this.props.widgets.map(widget => {
      return <Widget widget={widget}/>;
    });
  };

  render() {
    return (
      <div>
        <span>Hello, {this.props.user.name}</span>
        {this.renderWidgets()}
      </div>
    );
  }
}

export default Relay.createContainer(Dashboard, {
  fragments: {
    // `user` fragment is used by Dashboard
    user: () => Relay.QL`
      fragment on User {
        name
      }
    `,
    // Each widget have different fragment,
    // So what should be here?
  }
});

Update

I tried to make each ActualWidgetviewport. So, the circuit looks something like this:

type Viewer {
  widget1: Widget1
  widget2: Widget2
}

type Widget1 {
  name,
  fieldOnlyForWidget1
}

type Widget2 {
  name,
  fieldOnlyForWidget2
}

Then for my container, WidgetI try to insert the fragment dynamically.

export default Relay.createContainer(Widget, {
  initialVariables: {
    component: 'Widget1' // Trying to set the string here
  }

  fragments: {
    data: (variables) => Relay.QL`
      fragment on Viewer { # We now know it is Viewer type
        # This didn't work because `variables.component` is not string! :(
        ${widgetMap.get(variables.component).getFragment('viewer')}
      }
    `
  }
});

. , Relay QL , . .

RootContainer .

+4
1

, , , ( ). , , ; RootContainer -, , , .

, , , , . GraphQL: docs

" " "". "" , .

, Dashboard, :

var Dashboard = Relay.createContainer(DashboardComponent, {
  fragments: {
    dashboard: () => { console.log("dashboard query"); return Relay.QL`
      fragment on Dashboard {
        widgets {
          _typename
          ${FooWidget.getFragment("widget")}
          ${BarWidget.getFragment("widget")}
        }
      }
    `},
  }
});

"__typename", (. ). this.props.dashboard.widgets __typename, :

var widgets = this.props.dashboard.widgets.map((widget) => {
  if (widget.__typename == "FooWidget") {
    return <FooWidget widget={widget} />
  } else if (widget.__typename == "BarWidget") {
    return <CountdownWidget widget={widget} />
  }
})

, , . , Relay ( ), , , "Relay-ish" .

?

+4

Source: https://habr.com/ru/post/1621229/


All Articles