Creating Dash components that render other Dash components in their 'children' parameter

Hello,

I am trying to create a series of dash components by writing small components in react and then wrapping them for Dash.

I would like to be able to pass other Dash components such as html.H1, etc. to the react components, and then render them in the render() method.

I am wondering how this is achieved considering in the docs, it says:

  • Components in Dash are serialized as JSON. To write a Dash-compatible component, all of the props shared between the Python code and the React code―numbers, strings, booleans, as well as arrays or objects containing numbers, strings, or booleans―must be serializable as JSON. For example, JavaScript functions are not valid input arguments. In fact, if you try to add a function as a prop to your Dash component, you will see that the generated Python code for your component will not include that prop as part of your component’s accepted list of props. (It’s not going to be listed in the Keyword arguments enumeration or in the self._prop_names array of the generated Python file for your component).

For example, if I write:

app.layout = html.Div(
    children=[
        MyComponent.Simple(
            children=[
                html.Div("Test")
                ]
            )
        ]
    )

With this as my component:

class Simple extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <div className="app">
        It's Simple!
        {this.props.children.map((e, i) => e)}
      </div>
    );
  }
}

Simple.propTypes = {
  id: PropTypes.string,
  children: PropTypes.array,
  name: PropTypes.string,
};

export default Simple;

I get the following error:

this.props.children.map is not a function

But with anything serializable it of course works.

Thank you for any info!

If there is only one children in the list it get passed down as a single component. In dcc.Tabs we force the children to be an array if there is only one component.

I believe this is something that react has convenience methods for. Since children can be null, an object or an array, the React.Children.map function is designed to support this style of access.

Note that I haven’t actually verified this works, but I’ve been planning to switch to using that in some of my custom components as it becomes cumbersome to always need to check and coerce to an array.