skip to Main Content

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


  1. This is a somewhat dated pattern in React called "Render Props" (note the warning on the page):

    Render props are used in modern React, but aren’t very common.
    For many cases, they have been replaced by custom Hooks.

    As far as being an anti-pattern, it’s an expected feature of React and can still be useful in some niche circumstances.

    Login or Signup to reply.
  2. 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 a render prop, which is essentially the same concept but passed as a prop instead of children:

    <OptimizelyFeature
      feature="price_filter"
      render={(isEnabled, variables) => (
        isEnabled
          ? `Price filter enabled with a min price of ${variables.min_price}`
          : `Price filter is NOT enabled`
      )}
    />
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search