I noticed that Optimizely sdk suggest to implement the following like this and found it interesting.
<OptimizelyFeature feature="price_filter">
{(isEnabled, variables) => (
isEnabled
? `Price filter enabled with a min price of ${variables.min_price}`
: `Price filter is NOT enabled`
)}
</OptimizelyFeature>
in their code they basically do this
const FeatureComponent: React.FunctionComponent<FeatureProps> = props => {
const { feature, timeout, autoUpdate, children, overrideUserId, overrideAttributes } = props;
const [isEnabled, variables, clientReady, didTimeout] = useFeature(
feature,
{ timeout, autoUpdate },
{ overrideUserId, overrideAttributes }
);
if (!clientReady && !didTimeout) {
// Only block rendering while were waiting for the client within the allowed timeout.
return null;
}
// Wrap the return value here in a Fragment to please the HOC's expected React.ComponentType
// See https://github.com/DefinitelyTyped/DefinitelyTyped/issues/18051
return <>{children(isEnabled, variables, clientReady, didTimeout)}</>;
};
I’m wondering if this anti-pattern? isn’t a different type what they are passing?. Would it be better to pass it as a callback then the callback is used for rendering?
2
Answers
This is a somewhat dated pattern in React called "Render Props" (note the warning on the page):
As far as being an anti-pattern, it’s an expected feature of React and can still be useful in some niche circumstances.
Passing a callback as children in
React
, often referred to as the "Function as a Child Component" (FaCC
) pattern, is not considered an anti-pattern. It is a well-established and valid approach.An alternative to
FaCC
is to use arender prop
, which is essentially the same concept but passed as a prop instead ofchildren
: