Reputation: 6166
Having the following component:
import RadioButton from './radio-button';
import { Label, Horizontal, Vertical } from './radio-button.styles';
import { RadioOption, OptionGroup } from './radio-button.types';
export const UglyComponent = ({ label, options, horizontal, onChange }: OptionGroup) => {
function getRenderedOptions() {
return options.map(({ value, label }: RadioOption, index) => {
return (
<RadioButton
value={value}
label={label}
key={index}
/>
);
});
}
const renderedOptions = horizontal ? (
<Horizontal>{getRenderedOptions()}</Horizontal>
) : (
<Vertical>{getRenderedOptions()}</Vertical>
);
return (
<>
<Label>{label}</Label>
{renderedOptions}
</>
);
};
export default UglyComponent;
It kind of works, maybe the extra re-render after loading could be caused by the way its written, so instead of:
<Horizontal>{getRenderedOptions()}</Horizontal>
it could be used something like:
<Horizontal><GetRenderedOptions /></Horizontal>
?
Done it like follows:
import RadioButton from './radio-button';
import { Label, Horizontal, Vertical } from './radio-button.styles';
import { RadioOption, OptionGroup } from './radio-button.types';
export const RenderedOptions = ({ options, label, onChange }: OptionGroup) => {
return options.map(({ value, name, disabled }: RadioOption, index) => {
const optionLabel = label.replace(/ +/g, '-');
const optionId = `${optionLabel}-${index}`;
return (
<RadioButton
value={value}
label={label}
key={index}
/>
);
});
};
export const UglyComponent = ({ label, options, horizontal, onChange }: OptionGroup) => {
const renderedOptions = horizontal ? (
<Horizontal>
<RenderedOptions label={label} options={options} onChange={onChange} />
</Horizontal>
) : (
<Vertical>
<RenderedOptions label={label} options={options} onChange={onChange} />
</Vertical>
);
return (
<>
<Label>{label}</Label>
{renderedOptions}
</>
);
};
export default UglyComponent;
It doesn't work because it returns an array of components:
'RenderedOptions' cannot be used as a JSX component. Its return type 'Element[]' is not a valid JSX element.
Upvotes: 0
Views: 19
Reputation: 187004
Make it return one element instead with a fragment.
export const RenderedOptions = ({ options, label, onChange }: OptionGroup) => {
return <>{
options.map(({ value, name, disabled }: RadioOption, index) => {
const optionLabel = label.replace(/ +/g, '-');
const optionId = `${optionLabel}-${index}`;
return (
<RadioButton
value={value}
label={label}
key={index}
/>
);
})
}</>;
};
And now it's a component like any other:
<Horizontal>
<GetRenderedOptions
options={{ testing: 123 }}
label="Hello"
onChange={() => console.log('changed')}
/>
</Horizontal>
Upvotes: 1