Skip to content

Flatten frontend state? #189

@mosmuell

Description

@mosmuell

The frontend state is stored as the nested structure that is emitted from the backend:

const reducer = (state: State | null, action: Action): State | null => {
  switch (action.type) {
    case "SET_DATA":
      return action.data;
    case "UPDATE_ATTRIBUTE": {
      if (state === null) {
        return null;
      }
      return {
        ...state,
        value: setNestedValueByPath(
          state.value as Record<string, SerializedObject>,
          action.fullAccessPath,
          action.newValue,
        ),
      };
    }
    default:
      throw new Error();
  }
};

const App = () => {
  const [state, dispatch] = useReducer(reducer, null);

  useEffect(() => {
    socket.on("connect", () => {
      // Fetch data from the API when the client connects
      fetch(`${forwardedProto}://${authority}/service-properties`, {
        credentials: "include",
      })
        .then((response) => response.json())
        .then((data: State) => {
          dispatch({ type: "SET_DATA", data });
        });
  }, []);

When a nested dictionary updates, this causes rerenders of all components depending on parts of that nested dict, even if they did not change. To mitigate rerenders, I am passing a propsAreEqual function to React.memo:

export const MethodComponent = React.memo((props: MethodProps) => {
  ...
}, propsAreEqual);

By flattening the state structure, I could get rid of the propsAreEqual function, which would probably improve the performance.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestfrontendquestionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions