Keith Jackson Keith Jackson -4 years ago 137
React JSX Question

Render a single item from React.children - How?

I am trying to render a single item from React.props.children.

My usage looks like this...

render() {
return (
<DataListManager idName = "stops"
baseUrl={`/api/stop/${HiddenState.getAltId()}`}
errorProcessor={new ErrorProcessor()}
emptyMessage = "No stops have been added to this service yet."
confirmDeleteTitleCallback={(stop) => `Delete ${stop.name}?`}
confirmDeleteMessageCallback={(stop) => `Do you want to delete the stop ${stop.name}? This cannot be undone.`}>
<StopForm for="create"
formId="new-stop"
submitText="Add stop" />
<StopForm for="edit"
submitText="Update stop" />
</DataListManager>
);
}


I have 2 'StopForm' components, but I only want to render 1 of them dependent on the state of the component - The children are passed down a few layers to a toggle component that is generic for both create and edit scenarios. I want to render a different form for different scenarios.

Here is the method to render the edit view when creating a new item...

renderEdit(object, onCancelClickCallback, onSubmitSuccessCallback) {
const childrenWithProps = React.Children.map(this.props.children, (child) => React.cloneElement(child, {
stop: object,
onChange: this.onChange,
onSubmit: this.onSubmit,
onCancel: onCancelClickCallback,
onSubmitSuccess: onSubmitSuccessCallback
}));

childrenWithProps.forEach((child) => {
if (child.props.for == "create") {
return child;
}
});
}


(The render() method will call either renderEdit() or renderDisplay() dependent on it's state).

I can;t seem to get a single item to render however. I have tried the following variations but none have worked...

childrenWithProps.forEach((child) => {
if (child.props.for == "create") {
return <div>{child}</div>;
}
});

childrenWithProps.forEach((child) => {
if (child.props.for == "create") {
return {child};
}
});


Child seems to be a valid React object, yet I keep seeing this error...

render(): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.

Answer Source

You should not return in a forEach in the first place. Use filter or map to do the things you need.

const result = childrenWithProps.filter((child) => {
   return (child.props && child.props.for === "create");
}
return result[0] || null;
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download