-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Description
I have built an API in my React app using createApi(), but now later in development further requirements have arisen and I am not able to use the API in a straightforward way.
I am building a tree-like component, called a Selector, where the children of each node are potentially fetched on demand. The data model for this Selector looks like this:
export type SelectorDataFn = (parent?: SelectorItem) => SelectorItem[];
export type SelectorData = SelectorDataFn | SelectorItem[];
export interface SelectorItem {
id: ItemId;
entityType: EntityType;
description: string;
children?: SelectorData;
}
where (it now transpires) the SelectorDataFn on this first attempt pass would be a selector. This has introduced the consideration of some very smelly patterns, and some impossible ones too: having a useSelector() hook somewhere other than at the top level scope of the component.
The props for my Selector look like this:
interface Props {
rootItems: SelectorData;
icon: IconDefinition;
title: string;
onCancel?: () => void;
}
export const Selector = ({ rootItems, icon, title, onCancel }: Props) => {
// ...
}
I had considered creating a state or perhaps a memo of these selectors, creating them on demand and returning them from my SelectorItem.children, which seemed like a pitiful way to shoehorn my logic into RTKQ. I could then unwrap the selector in my SelectorColumn (think macOS Finder or Windows Explorer) using useSelector(), but I would have to pass in a dummy selector in the case that the SelectorItem had no children that simply retuned no data.
So my next thought was to address the store directly using connect(). But having a read around suggests that this is at best a pretty bad idea: dispatching actions manually and writing a mapStateToProps method.
Could anyone suggest an architecture that might work for this? ChatGPT let me down too 🤣😩