3

I need some input from people more experienced with Zustand to share their way of managing relational state. Currently we have the following:

Let's assume we have the example entities Campaign, Elementss and their Settings. The REST API returning them is in the following format:

GET <API>/campaigns/1?incl=elements,elements.settings

{
   "id":1,
   "name":"Welcome Campaign",
   "elements":[
      {
         "id":5,
         "type":"heading",
         "label":"Heading",
         "content":"Welcome!",
         "settings":[
            {
               "id":14,
               "name":"backgroundColor",
               "value":"#ffffff00"
            },
            {
               "id":15,
               "name":"color",
               "value":"#ffffff00"
            }
         ]
      },
      {
         "id":6,
         "type":"button",
         "label":"Button",
         "content":"Submit",
         "settings":[
            {
               "id":16,
               "name":"backgroundColor",
               "value":"#ffffff00"
            },
            {
               "id":17,
               "name":"color",
               "value":"#ffffff00"
            },
            {
              "id":18,
              "name":"borderRadius",
              "value":"3px"
            }
            ...
         ]
      }
      ...
   ]
}

What we are currently doing in the Reactjs app is fetching this data, then transforming it to the following normalized format and set functions:

const useCurrentCampaignStore = create(
  combine(
    {
      campaign: {
        id: 1,
        name: "Welcome Campaign"
      },
      elements: [
        {
          id: 5,
          campaignId: 1,
          type: "heading",
          label: "Heading",
          content: "Welcome!"
        },
        {
          id: 6,
          campaignId: 1,
          type: "button",
          label: "Button",
          content: "Submit"
        }
      ],
      settings: [
        {
          id: 14,
          elementId: 5,
          name: "backgroundColor",
          value: "#ffffff00"
        },
        {
          id: 15,
          elementId: 5,
          name: "color",
          value: "#ffffff00"
        },
        {
          id: 16,
          elementId: 6,
          name: "backgroundColor",
          value: "#ffffff00"
        },
        {
          id: 17,
          elementId: 6,
          name: "disabled",
          value: false
        },
        {
          id: 18,
          elementId: 6,
          name: "borderRadius",
          value: 3,
        }
      ]
    },
    set => ({
      updateSetting: (id: string | number, newValue: string | number | boolean) =>
        set(state => {
          const settings = [...state.settings];

          return {
            ...state,
            settings: settings.map(setting => {
              if (setting.id == id) {
                return { ...setting, value: newValue };
              }

              return setting;
            })
          };
        }),
      updateElementContent: (id: string | number, newValue: string) => {
        set(state => {
          const elements = [...state.elements];

          return {
            ...state,
            elements: elements.map(element => {
              if (element.id == id) {
                return { ...element, content: newValue };
              }

              return element;
            })
          };
        });
      }
    })
  )
);

I am, however, not sure this is the optimal solution, because It's rather tedious transforming all GET requests to a normalized format and then converting them back to nested objects when you want to construct either a POST, PUT or PATCH request.

So, to put it short, how do you guys design the state in your Zustand-based RESTful-API-backed React apps?

0 Answers0