Search code examples
reactjsconditional-renderingcatamorphismfantasyland

How to use daggy for conditional rendering in React


Lets say I have four components and I want to conditionally render them depending on a type prop using daggy:

In this example type prop value can be the string a, b, c or d

here is a working codesandbox example

import daggy from 'daggy';
import { componentA, componentB, componentC, componentD } from './components';

const UI = daggy.taggedSum('UI', {
  A: [],
  B: [],
  C: [],
  D: [],
});

const VIEWS = {
  a: UI.A,
  b: UI.B,
  c: UI.C,
  d: UI.D,
};

const getView = (type) => VIEWS[type];

export const Component = ({ type }) => {
  const view = getView(type);
  return view.cata({
    A: () => <ComponentA />,
    B: () => <ComponentB />,
    C: () => <ComponentC />,
    D: () => <ComponentD />,
  });
};

This works as expected, but it seems a little bit complicated and I feel like I'm missing something here, I've read the documentation but I could not really understand how to apply it to this simple example.

The examples I found on internet are too complex for what I want to achieve, which is just rendering a component using daggy depending on a prop.

Here is an example of conditional rendering using daggy, unfortunately it uses an additional library to achieve this and it seems more complex than my example.

If there is an alternative way to achieve conditional rendering in a similar fashion without using daggy it would also solve my problem.

Any suggestions?


Solution

  • You don't need to use daggy at all! You only need to map each component with type and render it.

    Try this:

    import * as React from "react";
    
    import { ComponentA } from "./ComponentA";
    import { ComponentB } from "./ComponentB";
    import { ComponentC } from "./ComponentC";
    import { ComponentD } from "./ComponentD";
    
    type ComponentProps = {
     type: string;
    };
    
    const componentVariants = {
      a: ComponentA,
      b: ComponentB,
      c: ComponentC,
      d: ComponentD
    };
    
    
    export const Component = ({ type, ...other }: ComponentProps) => {
      const Component = componentVariants[type];
      return <Component {...other} />;
    };